Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Advent of Code 2024

312 views
Skip to first unread message

Nivethan T

unread,
Nov 29, 2024, 9:48:45 AM11/29/24
to Pick and MultiValue Databases
It's that time of the year when it's too dark too early and too cold to be outside so let's stare at our computers a little longer.

Advent of Code (a daily coding puzzle until Christmas) is starting up in a couple days if anyone wants to jump in. I'll still be trying to solve the problems with Pick if anyone wants to jump in. Feel free to use any language though.


2023 Thread:

Jim Idle

unread,
Nov 30, 2024, 1:30:32 PM11/30/24
to mvd...@googlegroups.com
It’s an interesting thing for sure. Especially as MV Badic isn’t an ideal language for such things. If I have time, I will try sone of them this year. Assuming I can get a version of jBASE running ;)

--
You received this message because you are subscribed to
the "Pick and MultiValue Databases" group.
To post, email to: mvd...@googlegroups.com
To unsubscribe, email to: mvdbms+un...@googlegroups.com
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/mvdbms/3fd39bad-74af-43cb-9a75-df6f8b36ba78n%40googlegroups.com.

Nivethan T

unread,
Dec 1, 2024, 1:11:13 AM12/1/24
to Pick and MultiValue Databases
I hope you do, maybe we can get to 3 people this year if Optimus01010101 jumps on.

Day 1 this year is a nice easy one unlike last years.


A pick standard library would be nice for things like sorting. I also missed the UniVerse multivalued math functions like SUBS and MULS. If it pops up again I might try adding them to scarletdme as that would be useful.

Optimus01010101

unread,
Dec 1, 2024, 9:58:31 AM12/1/24
to Pick and MultiValue Databases
Well today is day 1. So, I'll start it. ;)

Ian McGowan

unread,
Dec 4, 2024, 10:26:18 PM12/4/24
to Pick and MultiValue Databases
Starting late, but intending to catch up :-)

Ian McGowan

unread,
Dec 5, 2024, 7:18:34 PM12/5/24
to Pick and MultiValue Databases
If it's pure string handling, MV Basic is surprisingly capable.  It's when the solution really needs regex or pointers that basic starts to creak.

I just did day 3, and a basic brute force approach is faster than python strings (and the python regex approaches are even slower, though a lot less lines of code).

ian:demo>AOC3.1
Multiplied total 1 is 196826776
Multiplied total 2 is 106780429
8 ms

$ time python aoc3.py
Multiplied total is: 196826776

real    0m0.168s


OSREAD MEM FROM 'AOC3.DAT' ELSE ABORT
CONVERT CHAR(10) TO "" IN MEM
*
M1=0
M2=0
DO.MUL=1
FOR C=1 TO LEN(MEM)
  IF MEM[C,4]='do()' THEN DO.MUL=1
  IF MEM[C,7]="don't()" THEN DO.MUL=0
  IF MEM[C,4]='mul(' THEN
    T=FIELD(MEM[C+4,LEN(MEM)],')',1) ;* Grab up to the next ')'
    V1=FIELD(T,',',1) ;* Grab the first value, this should be a number
    V2=FIELD(T,',',2) ;* Grab the second value, this should be a number
    V3=FIELD(T,',',3) ;* Grab the third value, this should be blank (there are 3 rows where it's not :-)
    IF V3 # '' THEN CONTINUE
    IF V1 # OCONV(V1,'MCN') THEN CONTINUE ;* Skip if not a number
    IF V2 # OCONV(V2,'MCN') THEN CONTINUE ;* Skip if not a number
    M1 += V1 * V2
    IF DO.MUL THEN M2 += V1 * V2
  END
NEXT C
CRT 'Multiplied total 1 is ':M1
CRT 'Multiplied total 2 is ':M2


Joe Goldthwaite

unread,
Dec 5, 2024, 11:37:37 PM12/5/24
to mvd...@googlegroups.com

I took a different approach using a state machine. I learned this when working with a compiler guy on the formula compiler for CompuSheet+. It makes for a larger program and one that looks a lot more complicated but once it's compiled it can be very efficient. It performs very similar to Ian's code but is a little slower than his.

The basic idea is that you keep track of the current state of your parsing to determine how to process the next character. At the beginning, there's no state. In that state the only characters you care about are "m" and "d" because that's the possible start of mul(xxx,xxx), do() and don't(). Once you hit that character  you know the next one needs to be a "u" or "o".  If it's not one of those then you reset the state and continue with the next character.

This process continues until you get to the final end parenthesis at which point you've got either a correct mul(xxx,xxx) expreression or the do() or don't(). If you get an invalid character at any point,  you reset the state and continue on looking for the next "m" or "d".

This can seem more complicated but if the rules are clearly defined it can be very flexible. As a bonus it can help you determine why an expression is wrong. Like if you wanted to flag any mul(xxx,xxx) that had alpha characters instead of numbers. This makes that sort of things easy.

>RUN BP.JG ADVENT.DAY.3
All Answer = 192767529
DO.MUL = 104083373

It took 21 ms

      OPEN 'BP.JG' TO F.BP.JG ELSE STOP 201,'BP.JG'

      READ LINES FROM F.BP.JG, 'ADVENT.DAY3.INPUT' ELSE STOP 202,'ADVENT.DAY3.INPUT'

      START = NOW()
      DO.MUL = 1
      CHR = ''
      
      GOSUB RESET.STATE
      DO.MUL.ANSWER = 0
      ANSWER = 0
      
      LOOP
         REMOVE LINE FROM LINES SETTING DELIM
         IF LINE NE '' THEN
            LN = LEN(LINE)
            FOR X = 1 TO LN
               CHR = LINE[X,1]
               BEGIN CASE
                  CASE STATE = ''
                     IF CHR = 'm' THEN
                        STATE = CHR
                     END ELSE
                        IF CHR = 'd' THEN
                           STATE = CHR
                        END ELSE
                           GOSUB RESET.STATE
                        END
                     END
                  CASE STATE = 'm'
                     IF CHR = 'u'THEN
                        STATE = CHR
                     END ELSE
                        GOSUB RESET.STATE
                     END
                  CASE STATE = 'u'
                     IF CHR = 'l' THEN
                        STATE = 'l'
                     END ELSE
                        GOSUB RESET.STATE
                     END
                  CASE STATE = 'l'
                     IF CHR = '(' THEN
                        STATE = CHR
                     END ELSE
                        GOSUB RESET.STATE
                     END
                  CASE STATE = '('
                     IF CHR >= '0' AND CHR <= '9' THEN
                        MUL1 := CHR
                     END ELSE
                        IF CHR = ',' THEN
                           STATE = CHR
                        END ELSE
                           GOSUB RESET.STATE
                        END
                     END
                  CASE STATE = ','
                     IF CHR >= 0 AND CHR <= '9' THEN
                        MUL2 := CHR
                     END ELSE
                        IF CHR = ')' THEN
                           *PRINT EXPRESSION
                           PRODUCT = MUL1*MUL2
                           *PRINT MUL1:'*':MUL2:'=':PRODUCT
                           ANSWER += PRODUCT
                           IF DO.MUL THEN
                              DO.MUL.ANSWER += PRODUCT
                           END
                        END
                        GOSUB RESET.STATE
                     END
                  CASE STATE = 'd'
                     IF CHR = 'o' THEN
                        STATE = CHR
                     END ELSE
                        GOSUB RESET.STATE
                     END
                  CASE STATE = 'o'
                     IF CHR = '(' THEN
                        STATE = 'o('
                     END ELSE
                        IF CHR = 'n' THEN
                           STATE = CHR
                        END ELSE
                           GOSUB RESET.STATE
                        END
                     END
                  CASE STATE = 'o('
                     IF CHR = ')' THEN
                        DO.MUL = 1
                     END
                     GOSUB RESET.STATE
                  CASE STATE = 'n'
                     IF CHR = "'" THEN
                        STATE = CHR
                     END ELSE
                        GOSUB RESET.STATE
                     END
                  CASE STATE = "'"
                     IF CHR = 't' THEN
                        STATE = CHR
                     END ELSE
                        GOSUB RESET.STATE
                     END
                  CASE STATE = 't'
                     IF CHR = '(' THEN
                        STATE = 't('
                     END ELSE
                        GOSUB RESET.STATE
                     END
                  CASE STATE = 't('
                     IF CHR = ')' THEN
                        DO.MUL = 0
                     END
                     GOSUB RESET.STATE
                  CASE 1
                     GOSUB RESET.STATE
               END CASE
            NEXT
         END
      UNTIL DELIM = 0 DO
      REPEAT

      MILLISECONDS = NOW() - START
      PRINT 'All Answer = ':ANSWER
      PRINT 'DO.MUL = ':DO.MUL.ANSWER
      PRINT
      PRINT 'It took ':MILLISECONDS:' ms'

      STOP

RESET.STATE:
      IF CHR = 'm' OR CHR = 'd' THEN
         STATE = CHR
      END ELSE
         STATE = ''
      END
      MUL1 = ''
      MUL2 = ''
      RETURN

Ian McGowan

unread,
Dec 6, 2024, 1:29:34 AM12/6/24
to Pick and MultiValue Databases
>> I took a different approach using a state machine. I learned this when working with a compiler guy on the formula compiler for CompuSheet+. It makes for a larger program and 
>> one that looks a lot more complicated but once it's compiled it can be very efficient. It performs very similar to Ian's code but is a little slower than his.

That's a super interesting approach.  If you had to do more complex processing with different syntax the state machine would be easy to modify, but my FIELD approach would fall apart.  It already did - there are some numbers with commas after them, so had to add a klugey check just for some weird data.

It's fascinating how everyone has a different take on how to do it.  I saw Nivethan using MATCHES in their answer, would never in a million years thought of that!  My answers seem not very clever and brute force by comparison :-)

Ian McGowan

unread,
Dec 6, 2024, 1:46:40 AM12/6/24
to Pick and MultiValue Databases
Another interesting thing comparing to other language solutions on reddit.com/r/adventofcode discussions, the MV Basic ones I'm writing are brute force, but they are usually much shorter than many of the alternatives.  Except for Prolog and Haskell solutions, and some clever Python ones :-)

ian:demo>AOC4.1
XMAS Count: 2583
98 ms

ian:demo>AOC4.2
X-MAS Count: 1978
74 ms


OSREAD WORDS.RAW FROM 'AOC4.DAT' ELSE ABORT
CONVERT CHAR(10) TO @AM IN WORDS.RAW
WORDS=''
FOR R=1 TO DCOUNT(WORDS.RAW,@AM)
  FOR C=1 TO LEN(WORDS.RAW<R>)
    WORDS<R,-1>=WORDS.RAW<R>[C,1]
  NEXT C
NEXT R
*
MAX.R=DCOUNT(WORDS, @AM)
MAX.C=DCOUNT(WORDS<1>,@VM) ;* Assume all rows are the same length
XMAS.COUNT=0
FOR R=1 TO DCOUNT(WORDS,@AM)
  FOR C=1 TO DCOUNT(WORDS<R>,@VM)
    IF WORDS<R,C> # 'A' THEN CONTINUE ;* Starting point will always be an A
    IF R=1 OR C=1 OR R=MAX.R OR C=MAX.C THEN CONTINUE ;* Skip the edges
    * Check all 4 diagonals, skip up, down, left, right; preface with D to avoid reserved words
    DNW=WORDS<R-1,C-1>
    DNE=WORDS<R-1,C+1>
    DSW=WORDS<R+1,C-1>
    DSE=WORDS<R+1,C+1>
    MAS.COUNT=0
    IF (DNW = 'S' AND DSE = 'M') OR (DNW = 'M' AND DSE = 'S') THEN MAS.COUNT+=1
    IF (DNE = 'S' AND DSW = 'M') OR (DNE = 'M' AND DSW = 'S') THEN MAS.COUNT+=1
    IF MAS.COUNT=2 THEN XMAS.COUNT+=1
  NEXT C
NEXT R
CRT 'X-MAS Count: ':XMAS.COUNT
STOP
*


Wols Lists

unread,
Dec 6, 2024, 3:38:01 AM12/6/24
to mvd...@googlegroups.com
On 06/12/2024 06:29, Ian McGowan wrote:
> That's a super interesting approach.  If you had to do more complex
> processing with different syntax the state machine would be easy to
> modify, but my FIELD approach would fall apart.  It already did - there
> are some numbers with commas after them, so had to add a klugey check
> just for some weird data.
>
> It's fascinating how everyone has a different take on how to do it.  I
> saw Nivethan using MATCHES in their answer, would never in a million
> years thought of that!  My answers seem not very clever and brute force
> by comparison :-)

Jo said all the letters you care about initially are m and d. When I was
working on a (simple) arithmetic parser, I used matparse (the 2d version)

dim matexpr (100,2)

matexpr = matparse( expression, "()*/+-") ;* (and possibly a bit else
besides)

Here I'd parse on m and d. So all your m's and d's would end up in
matexpr(x,2), and all your matexpr(x,1) should start with "ust", "o", or
"on't". Take it from there ...

I've been looking at all this and wishing I could find time to do it ...

Cheers,
Wol

Ian McGowan

unread,
Dec 6, 2024, 3:53:42 PM12/6/24
to Pick and MultiValue Databases
They start out easy, so doesn't take too long for the first few days.  Difficulty increases as it goes along - I'm hoping to make it to day 10, and then may drop off.

Nivethan T

unread,
Dec 7, 2024, 1:22:52 AM12/7/24
to Pick and MultiValue Databases
Good to see more people :)

I've already fallen behind, here is day 3: https://github.com/Krowemoh/AOC-2024/blob/main/AOC.2024.03

I used MATCHFIELD and it seemed to work well enough though it feels quite brittle. Interesting to see the different ways to solve the same thing.

I need to start timing these routines.

Joe Goldthwaite

unread,
Dec 7, 2024, 11:36:47 AM12/7/24
to mvd...@googlegroups.com
Day 6

I was playing with this with my friend Heath. While we were trying to
debug it I got the idea of showing the path while it was running.

https://github.com/jgoldgh/AOC-2024/blob/main/ADVENT.DAY.6

You need a terminal screen that's at least 133 columns by 133 rows to
get it to display correctly. When it starts you have to hit a key to go
step by step. If you hit "Q" it will quit and "C" will make it continue
until it's done. The results show at the bottom.

I haven't tried posting a github link before so let me know if there are
any issues.


Joe Goldthwaite



Ian McGowan

unread,
Dec 8, 2024, 4:48:33 AM12/8/24
to Pick and MultiValue Databases
Link came through fine - I liked your idea of showing a little animation of the map, and changing the character to represent the direction (which turns out to be important in part 2).


Part 2 is fun - brute force works fine for this one, surpisingly!

...
ROW 129
ROW 130
Obstacle count=1911
51482 ms


AOC6.1.gif

Ian McGowan

unread,
Dec 8, 2024, 4:56:05 AM12/8/24
to Pick and MultiValue Databases
>>I've already fallen behind, here is day 3: https://github.com/Krowemoh/AOC-2024/blob/main/AOC.2024.03
>>I need to start timing these routines.

Not too late to catch up, but day 5 is a tough one!

You should add something to your NSH program to automatically show the execute time of commands in ms.  In my shell (which confusingly is called STACK), ".T" toggles showing the timing of commands.  Sadly only for Unidata right now.

Joe Goldthwaite

unread,
Dec 8, 2024, 1:44:04 PM12/8/24
to mvd...@googlegroups.com

Thanks! I had that idea to help with debugging. It does help although even on my 43" 4k display the characters are difficult to read at 134 columns X 134 rows.

I tried part 2 yesterday but haven't gotten a correct answer yet. I might try working on it again if I have time today.

Ian McGowan

unread,
Dec 8, 2024, 8:49:25 PM12/8/24
to Pick and MultiValue Databases
The key thing with part 2 is that visiting the same cell doesn't count as a loop - you have to visit the same cell headed in the same direction.  And the starting point cannot have a block, if you're off by 1 :-)

And a performance thing that helps if you're doing brute force, no need to simulate a run with a block in a position that the guard never visits - it went from 5 minutes to 40 seconds when I made that change...

Nivethan T

unread,
Dec 8, 2024, 11:40:05 PM12/8/24
to Pick and MultiValue Databases
>>You should add something to your NSH program to automatically show the execute time of commands in ms.  In my shell (which confusingly is called STACK), ".T" toggles showing the timing of commands.  Sadly only for Unidata right now.

This was a good idea, I've update NSH now where I can trigger a timer mode :) I tried to compile STACK in ScarletDME but it looks a bit troublesome with the OSREADs but I may gave it a shot as I think it would be a fun exercise.

I didn't realize that you had a shell and the source code was up, I can already see that I want to steal the way you display the help. I'm terrible at documenting so having it be in the code would probably go a long way.



Finished up days 4, 5, 6, 7 - I skipped day 6 part 2 because it looked difficult and my brain is tired.


Day 7 was the most cheaty day. I precomputed the combinations of all the operators and then used that to process things. I'm actually still waiting to generate the 11th round and may give up. Just brute forcing things might be over now lol.

Also the animations of the guard walking is great fun.

Nivethan T

unread,
Dec 9, 2024, 12:44:18 AM12/9/24
to Pick and MultiValue Databases
I finished day 7 but it definitely took awhile to do the brute forcing. I used my template engine to evaluate generated code and it choked on round 11. I had it generate the combination generator to a file and the compiled version ran in a few seconds. Something to look at as I need to speed up my templating engine.


We're getting to the hard days!

Ian McGowan

unread,
Dec 9, 2024, 3:22:14 AM12/9/24
to Pick and MultiValue Databases
Everyone should write a shell, at least once :)

I had a different version that didn't have all those InfoLease things in there.  It's much smaller without those, and no OSREAD.  Probably need to replace IN() with KEYIN() or whatever command gets a character from the typeahead buffer.

The two best things are being able to edit and recall commands with editing keys, and working with programs I tend to save in VSCode, flip over to a terminal and do /B to compile, then /R to run.  Makes the REPL cycle quicker.

Tom Marracci

unread,
Dec 9, 2024, 10:32:41 AM12/9/24
to mvd...@googlegroups.com, and MultiValue Databases Pick
Rather than making my own permutations of + and * I used binary and then mod to decide whether to add or multiply and int(/2) to get to the next bit.   Then it’s just a loop of 2^m-1 to find the match


Tom

Sent from my iPhone

On Dec 9, 2024, at 12:22 AM, Ian McGowan <ian.m...@gmail.com> wrote:

Everyone should write a shell, at least once :)
--
You received this message because you are subscribed to
the "Pick and MultiValue Databases" group.
To post, email to: mvd...@googlegroups.com
To unsubscribe, email to: mvdbms+un...@googlegroups.com
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.

Ian McGowan

unread,
Dec 10, 2024, 2:04:36 AM12/10/24
to Pick and MultiValue Databases
>> I used binary and then mod to decide whether to add or multiply and int(/2) to get to the next bit.

But then comes part 2 - there's another operator in the mix :-)  Curious to see how other people coded this in Basic...  Getting less sure about getting past day 10...  Day 7 was tough.


One interesting thing in Unidata (that's relatively recent in PICK terms) is the ability to have a local subroutine or function.  Useful in this case because I couldn't wrap my head around making all possible operator combos iteratively.

ian:demo>AOC7.1
Total calibration result=882304362421
1049 ms

ian:demo>AOC7.2
Total calibration result=145149066755184
48690 ms

OSREAD EQUATIONS FROM 'AOC7.DAT' ELSE ABORT
CONVERT CHAR(10) TO @AM IN EQUATIONS
NUM.EQUATIONS=DCOUNT(EQUATIONS,@AM)
DEL EQUATIONS<NUM.EQUATIONS> ; NUM.EQUATIONS -= 1
OPERS='+':@VM:'*'
*
TOTAL.CAL.RESULT=0
MEMOS=''
FOR EQN.NUM=1 TO NUM.EQUATIONS
  TEST=FIELD(EQUATIONS<EQN.NUM>,':',1)
  VALS=TRIM(FIELD(EQUATIONS<EQN.NUM>,':',2))
  CONVERT ' ' TO @VM IN VALS
  GOSUB GEN.PERMUTATIONS
  GOSUB CHECK.EQN
NEXT EQN.NUM
CRT 'Total calibration result=':TOTAL.CAL.RESULT
STOP
*
GEN.PERMUTATIONS:
  N=COUNT(VALS,@VM) ;* Not DCOUNT!
  IF MEMOS<N> # '' THEN
    * The permutations are the same if the number of values are the same.  Memoize.
    PERMUTATIONS=MEMOS<N>
  END ELSE
    PERMUTATIONS=''
    * Generate a string with all possible permutations of the operators
    * Note: this will create a *big* dynamic array - 3^12 = 531,441 combinations
    CALL GEN('',N,PERMUTATIONS)
    MEMOS<N>=PERMUTATIONS
  END
RETURN
*
CHECK.EQN:
  * Check all possible permutations to see if any match the TEST value
  LOOP
    REMOVE PERM FROM PERMUTATIONS SETTING MORE
    NUM.VALS=DCOUNT(VALS<1>,@VM)
    * Do a quick check before trying this permutation
    * a) if the last oper is : then the last digits should match, or
    * b) if the last oper is * then should be divisible exactly
    LAST.OP=PERM[LEN(PERM),1]
    LAST.VAL=VALS<1,NUM.VALS>
    IF LAST.OP=':' THEN
      TEST.STR=TEST[LEN(TEST)-LEN(LAST.VAL)+1,LEN(LAST.VAL)]
      IF LAST.VAL # TEST.STR THEN CONTINUE
    END
    IF LAST.OP='*' THEN
      IF TEST/LAST.VAL # INT(TEST/LAST.VAL) THEN CONTINUE
    END
    *
    TOTAL=VALS<1,1> ;* No operator precedence, just start with the 1st and YOLO from there
    FOR V=2 TO DCOUNT(VALS<1>,@VM)
      NEXT.VAL=VALS<1,V>
      OP=PERM[V-1,1]
      BEGIN CASE
        CASE OP='+'
          TOTAL+=NEXT.VAL
        CASE OP='*'
          TOTAL*=NEXT.VAL
        CASE OP=':'
          TOTAL:=NEXT.VAL
      END CASE
      IF TOTAL > TEST THEN EXIT ;* Not gonna get any smaller, may as well bail once we're bigger than TEST
    NEXT V
    IF TOTAL = TEST THEN
      TOTAL.CAL.RESULT+=TOTAL ; EXIT ;* Don't need to try all the rest, just one matching will do
    END
  WHILE MORE DO
  REPEAT
RETURN
*
SUBROUTINE GEN(PREFIX, L, RESULT)
  * Thanks ChatGPT for the recursive algo - it works, but breaks my brain trying to understand how...
  * Local functions in U2 are a nice addition!
  TOKENS = '+':@VM:'*':@VM:':'
  IF L = 0 THEN
    RESULT<1,-1>=PREFIX
    RETURN
  END
  *
  FOR F=1 TO DCOUNT(TOKENS<1>,@VM)
    TOKEN=TOKENS<1,F>
    CALL GEN(PREFIX:TOKEN, L-1, RESULT)
  NEXT F
RETURN
*

Ian McGowan

unread,
Dec 10, 2024, 2:10:37 AM12/10/24
to Pick and MultiValue Databases
>> I used my template engine to evaluate generated code and it choked on round 11. I had it generate the combination generator to a file and the compiled version ran in a few seconds. Something to look at as I need to speed up my templating engine.

How big was that generated code file?  For some of the full set there are 12 numbers, and with 3 operators that means 3^12 = 531,441 combinations.

Anyone remember the days of 512KB limits on object code? :-)

Nivethan T

unread,
Dec 10, 2024, 9:29:34 AM12/10/24
to Pick and MultiValue Databases
my permutation generator helper routine:

I couldn't wrap my head around permutations at all and so went with the most brain dead solution. I checked for the longest set of numbers then generated each set of permutations and stuck it in a file. This process made adding a 3rd operator trivial luckily.

Day 9 is straightforward enough but I'm at the point where I'm aiming to get a single star now.

Nivethan T

unread,
Dec 10, 2024, 9:30:34 AM12/10/24
to Pick and MultiValue Databases
Wait a minute, does unidata have real scope and local subroutines, can you have s many as you want?

That looks magical.

Ian McGowan

unread,
Dec 10, 2024, 10:52:29 AM12/10/24
to Pick and MultiValue Databases
Yes!  I believe Universe had them first.  It's magical in two senses - a) it's bringing PICK Basic into the 90's :-), and b) I believe the subroutine or function gets split out to some system generated object and compiled independently.  So it's almost a trick of the precompiler, not the basic runtime.  It made the debugger a little confused when running from within my STACK program...

tomma...@aircraftspruce.com

unread,
Dec 10, 2024, 11:26:04 AM12/10/24
to mvd...@googlegroups.com

Ian,

 

When you notice that the following permutation:

 

+++

++*

+*+

+**

*++

*+*

**+

***

 

is just 8 binary numbers (replace + with 0 and * with 1), you’ll see that you can use the following code with no permutation preprocessing:

 

195   M = DCOUNT(TERMS,CHAR(254))

196   MAX = 2^(M-1)

197   FOR I = 0 TO MAX-1 UNTIL SUM = VAL

198     OP = I

199 * USE BINARY NUMBERS TO PERFORM PERMUTATIONS OF +*

200     SUM = TERMS<1>

201     FOR J = 2 TO M UNTIL SUM > VAL

202       X = MOD(OP,2)

203       IF X=0 THEN SUM += TERMS<J> ELSE IF X=1 THEN SUM *= TERMS<J>

204       OP = INT(OP/2)

205     NEXT J

206   NEXT I

 

And likewise for 3 operations, use base 3 instead of base 2.  It’s still brute force to apply these operations, but if there is a way to avoid nested loops, I couldn’t find it.

 

Tom

 

 

tomma...@aircraftspruce.com

unread,
Dec 10, 2024, 12:03:11 PM12/10/24
to mvd...@googlegroups.com

Don’t be afraid of 10 day. It’s just a DFS and count the number of paths from each 0 to each 9.

 

Tom

 

 

From: mvd...@googlegroups.com <mvd...@googlegroups.com> On Behalf Of Ian McGowan
Sent: Tuesday, December 10, 2024 7:52 AM
To: Pick and MultiValue Databases <mvd...@googlegroups.com>
Subject: Re: [mvdbms] Advent of Code 2024

 

Yes!  I believe Universe had them first.  It's magical in two senses - a) it's bringing PICK Basic into the 90's :-), and b) I believe the subroutine or function gets split out to some system generated object and compiled independently.  So it's almost a trick of the precompiler, not the basic runtime.  It made the debugger a little confused when running from within my STACK program...

Wols Lists

unread,
Dec 10, 2024, 1:31:01 PM12/10/24
to mvd...@googlegroups.com
On 10/12/2024 15:52, Ian McGowan wrote:
> Yes!  I believe Universe had them first.

And I believe QM beat them all ...

Cheers,
Wol

Joe Goldthwaite

unread,
Dec 10, 2024, 1:33:55 PM12/10/24
to mvd...@googlegroups.com
Wow! Next you're going to tell is that QM has classes and supports
equated variables in the debugger.
> --
> You received this message because you are subscribed to
> the "Pick and MultiValue Databases" group.
> To post, email to: mvd...@googlegroups.com
> To unsubscribe, email to: mvdbms+un...@googlegroups.com
> For more options, visit http://groups.google.com/group/mvdbms
> ---
> You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/mvdbms/8a863ab5-f24e-431f-b7ff-70de9d534178%40youngman.org.uk.

Nivethan T

unread,
Dec 10, 2024, 2:01:51 PM12/10/24
to Pick and MultiValue Databases
Well Today I learned, Universe does indeed have it, I've never used it till now. This is going to be handy. :)

Some day I'll use QM enough to try the latest and greatest, the json handling looks quite nice.

Ian McGowan

unread,
Dec 10, 2024, 10:42:01 PM12/10/24
to Pick and MultiValue Databases
"The real lesson was the friends we made along the way" :-)

This is my first time doing AOC, but I've already noticed a small difference when going back to my regular day job programming (which to be honest is 90% "read in some slop, transform it a little, write out some different slop") - for the 10% that's not super obvious I might think a little more about data structures and algorithms after this...

Jim Idle

unread,
Dec 11, 2024, 10:44:04 AM12/11/24
to mvd...@googlegroups.com
jBASE has had such things for a very long time, well before QM and Universe. Including reading and writing to JSON. X->y etc. and embedding C directly within the language (not a requirement but useful). It is all embedded within the compiler. We had variables in the debugger since around 1991, as well as conditional breakpoints, trace points, debugging scripts and bunches of other stuff. It also has highly performant zero maintenance files, transactions and compiled query support. 

Reply all
Reply to author
Forward
0 new messages