Advent of Code 2024

ChatGPT >>

“The Advent of Code is an annual online event and programming challenge that takes place in December. Each day, a new puzzle or coding challenge is released, and participants are encouraged to solve them using their programming skills. The challenges are designed to be fun, creative, and challenging, and often require problem-solving and critical thinking skills. The event has gained popularity among programmers and coding enthusiasts as a way to improve their skills, compete with others, and have fun during the holiday season.”

I’d like to encourage lots of Delphi people to have a crack and maybe compare solutions - online or at a meeting.

Each day is pretty much independent of the others … but the concepts might build upon previous days’ puzzles.

Fun starts on 1st December. Link → The Advent of Code 2024

Maybe use it to learn a new language …

Or new data structures, or algorithms, …

Or a library like Spring4D …

[ … was video “Behind the scenes of AoC” ]

Paul_McGee the last thing is to be rude to you as I know you know your stuff - but I feel you need something to find your self in. Something that gives you a challenge and may use more than one language may be. To me you seem to be the type of person that needs to take up a good challenge for your self to get personal satisfaction. May be a type of bit code version of PHP or another language based in C ++ but do not start it as a Joke. at the end of the day you have to find you in what ever you do. But you have to turn from learning to doing and in doing as a freelancer that you realize a gap if what is not been done that can be for you. Is that helpful to you?
People can debate languages with many pros and cons
example is their a faster language to build a database App with. every lanauage

.

First problem, first day.

This is the code we might write :

const N = 1000;
begin
   TArray.Sort<integer>(data1);
   TArray.Sort<integer>(data2);

   var total := 0;
   for var i := 0 to N-1 do inc(total, abs( data1[i]-data2[i] ) );

This is the code I want to be able to write :

   var data1 := TList.Create(data_1);
   var data2 := TList.Create(data_2);

   data1.Sort;
   data2.Sort;

   var data  := ZipTransform(data1, data2, delta);
   var total := List_Reduce(data, sum); 

Instead it is currently :

   var data1 := TList<integer>.Create(data_1);
   var data2 := TList<integer>.Create(data_2);

   data1.Sort;
   data2.Sort;

   var data  := UFP.ZipTransform<integer, integer, integer>(data1, data2, delta);
   var total := UFP.List_Reduce<integer>(data, sum);

By the way … the same code in APL … :smiley:

+/ | A-B

From Claude.io :

Let me break this down:

  • A - B performs element-wise subtraction between the two arrays
  • | is the APL absolute value function, which takes the absolute value of each element
  • +/ is the reduction (sum) operator that adds up all the elements

For example:

A ← 1 2 3 4
B ← 5 4 3 2
+/|A - B         ⍝ Would return 8

In this case, the absolute differences would be |1-5|, |2-4|, |3-3|, |4-2|, which are 4, 2, 0, 2, and their sum is 8.

This concise one-line expression is characteristic of APL’s dense and expressive syntax, allowing complex operations to be performed with minimal code.

Oops. I forgot the sorting …

Claude says :

SortSumDiff ← (+/|) ∘ (-/) ∘ (⍋¨)

Essentially, from right to left : Creating a sort index, subtracting, absoluting, and summing. :no_mouth::sweat_smile:

The thing is, One has to decide whether code should be succinct or readable, preferably both. I would suggest that the line above is definitely succinct, to the point of being terse - but is it easily readable to someone else maintaining that code, potentially years later? I’d say, based on a 40-year career as a professional developer working in a broad array of languages, it’s not.

In fact, the line of code looks very much like the Brainf*ck language and that’s not a good thing… :joy:

(Note that the link and its destination are NSFW)

And that’s the reason why so many different programming languages exist. Opinions, perceived imperfections, or just general “I want a language that does things a different way”.

1 Like

Conor Hoekstra had made many many videos about different languages, often comparing several on the same problem. (BIG recommend for his YouTube channel)

He has made a pretty good point, I think, about the APL- like array languages, comparing it to eg chinese.

Chinese writing would be super unfamiliar to most of us … but very readable, of course, to a HUGE number of people. So (he says) the issue is being unfamiliar, rather than inscrutable.

Also like Chinese symbols, the glyphs of APL have a visual meaning that reflects the operations they implement.

There’s a great story behind this about Ken Iverson who won a Turing Award for the notation he created in “Notation as a Tool of Thought”. (That only turned into a programming language as an after thought)

I can’t read it and don’t use it … but it’s interesting to know about imo.

Also, apparently, groups of symbols form recognisable idioms … so they can be understood together at a glance.

Should I mention here that I’ve written programs in the past using Forth? A few months of that and you forget how to do basic math in real life (“What, you mean the world doesn’t all use RPN?”).

That, and Perl, which, like most RegEx things, was obviously invented by someone who dropped their peyote stash on a keyboard and said “heyyyyy, I invented a new language”. :clown_face:

1 Like
  TEnumerable.Zip<Integer,Integer,Integer>(left.Ordered, right.Ordered,
    function(const left, right: Integer): Integer
    begin
      Result := Abs(left - right);
    end).Sum;

:sunglasses:

3 Likes

You know @sglienke ,

We’d love to have you demonstrate the problems (or some of) in Spring4D …

and we could feature them here in a thread and all learn about it together !?

:slight_smile:

Puppy Begging gifs - Find & Share on GIPHY

Rust.

pub fn main() {
    let mut vec1 = DATA1;
    let mut vec2 = DATA2;

    vec1.sort();
    vec2.sort();

    let result:i32 = vec1.iter()
                         .zip ( vec2.iter() )
                         .map ( |(x, y)| diff(x,y) )
                         .sum ();

    println!("Difference sum: {}", result);
}

fn diff(x: &i32, y: &i32) -> i32 { (x-y).abs() }

Day 1 - part 2:

  var rightCounted := TCollections.CreateMultiSet<Integer>(right);
  var similarityScore := left.Sum(
    function(const i: Integer): Integer
    begin
      Result := i * rightCounted.ItemCount[i];
    end);
2 Likes

My attempt is less concise.

begin
       var c    := 0;
       var dict := TDictionary<integer,integer>.Create;

       for var d in data_2 do
           if dict.TryGetValue(d,c) then dict.AddOrSetValue(d,c+1)
                                    else dict.Add(d,1);

       var counts := TList<integer>.Create;
       var data1  := TList<integer>.Create(data_1);

       for var d in data1 do 
           if dict.TryGetValue(d,c) then counts.add(c)
                                    else counts.add(0);

       var data   := UFP.ZipTransform<integer, integer, integer>(data1, counts, mult);
                   { ZipTransform(data1,counts,mult) }
       var total  := UFP.List_Reduce<integer>(data, sum, 0);
                   { List_Reduce(data,sum) }

       writeln(total);           // 23963899
       dict.free;
       readln;
end.

A fun challenge here for Question 5 Part 2 that I am liking.

A path to the solution.