Advent of Code 2025

Following on from Advent of Code 2024 , the Advent of Code 2025 has started :grinning_face:

It lasts for 12 days.

My solutions will be at advent-of-code/2025 at main · brebs-gh/advent-of-code · GitHub

Day 1 part 2 was a bit fiddly, getting the number of times that 0 is crossed over, without double-counting.

4 Likes

I enjoyed using Prolog last year. Same plan this year.

2 Likes

I’m doing it in Scryer Prolog this year: https://garklein.github.io/aoc25pl/

So far, it has been quite tricky, especially for a Prolog noob like me… today took many hours of head-scratching before I found a solution that runs in a reasonable amount of time (~10s).

Companion discussions: Advent of Code 2025 · mthom/scryer-prolog · Discussion #3184 · GitHub (I know this isn’t SWI Prolog, but the Prolog community is so small that I am curious to see others’ solutions, even in a different dialect of Prolog, and I hope you will enjoy my solutions as well)

3 Likes

For day 2: part 1 was fast in clpfd… then part 2 appeared, which was not really suitable for clpfd, so I switched the methods to list processing :grinning_face:

Thanks @brebs and everybody else for contributing to this thread.

I’ve uploaded the days so far at advent_of_code/swipl/2025 at main · CapelliC/advent_of_code · GitHub .

There are also my solutions in Dart, that i started studying recently because I’m commiting to Flutter.

And I hope I’ll find the time to upload some selected Picat as well (maybe just in case the language really helps).

1 Like

I have done Day 1 in JavaScript, where it boils down to an aggregation over some math formula:

My open question for you is: is there a Prolog-ish (relational?) way of thinking about these problems or are these indeed just “functional”?

(function () {
  "use strict";

  const PERIOD = 100;
  const INITIAL = 50;

  /**
   * Returns the number of times the dial is left
   * pointing at 0 after any rotation in the sequence.
   * 
   * @param {string} data
   * @returns {number}
   */
  function prob_1_1(data) {
    var pos = INITIAL;
    var cnt = 0;

    data.split(/\s+/g).forEach((move) => {
      move = move.trim();

      var mdir = move[0];
      var mval = parseInt(move.substring(1), 10);

      if (mdir === "L") {  // rot neg
        pos -= mval % PERIOD;
        pos += PERIOD;
        pos %= PERIOD;
      }
      else {               // rot pos
        pos += mval;
        pos %= PERIOD;
      }

      if (pos === 0) {
        ++cnt;
      }
    });

    return cnt;  // 3; 1055
  }

  /**
   * Returns the number of times any click causes
   * the dial to point at 0, regardless of whether it
   * happens during a rotation or at the end of one.
   * 
   * @param {string} data
   * @returns {number}
   */
  function prob_1_2(data) {
    var pos = INITIAL;
    var cnt = 0;

    data.split(/\s+/g).forEach((move) => {
      move = move.trim();

      var mdir = move[0];
      var mval = parseInt(move.substring(1), 10);

      const posIs0 = pos == 0;

      if (mdir === "L") {  // rot neg
        pos -= mval % PERIOD;
        if (!posIs0 && pos <= 0) { ++cnt; }
        pos += PERIOD;
        pos %= PERIOD;
        cnt += Math.floor(mval / PERIOD);
        //console.log(`L${mval} -> ${pos} [${cnt}]`);
      }
      else {               // rot pos
        pos += mval % PERIOD;
        if (!posIs0 && pos >= PERIOD) { ++cnt; }
        pos %= PERIOD;
        cnt += Math.floor(mval / PERIOD);
        //console.log(`R${mval} -> ${pos} [${cnt}]`);
      }
    });

    return cnt;  // 6; 6386
  }

  const DATA = Object.freeze({
    "test": "L68 L30 R48 L5 R60 L55 L1 L99 R14 L82",
    "case": "L44 R35 R4 L40 L13 L7 L33 L8 L44 L39 L45 R30 R38 L10 L40 L8 L10 L27 L47 R31 R41 L21 R5 L38 R41 L35 R16 R44 L37 L28 L36 R5 R25 R36 R16 L21 L23 L46 L36 R27 R43 R48 L14 L26 R24 L18 L23 R39 L30 R84 L79 L73 R17 R9 L9 L30 R74 L44 L67 L19 L14 L23 R23 R62 L70 R96 R12 L37 R47 L43 L28 L39 L13 L85 R12 L55 L22 L39 R37 R36 L17 R46 R91 R49 R62 L52 R50 R81 L54 R73 L62 R73 R66 L92 R31 L98 L59 R78 L80 R45 L2 R67 L677 L39 R3 R575 R71 R19 L29 L38 R20 R776 R3 L12 L43 R99 L795 R40 L49 R609 R81 R19 L91 R14 L14 R192 R99 R92 R34 L26 L12 R84 R31 L3 L348 R98 R50 R40 L40 L459 L96 L203 L836 R35 R74 L96 R681 R91 R9 L41 R41 R99 L99 L3 R3 R429 R45 L74 L101 R901 L43 R18 R25 L2 L18 R61 L42 L30 L39 L376 R55 R52 R6 R77 R90 R66 L71 R59 L88 R380 R58 R949 L87 R48 L22 L13 L92 R90 R61 R28 L54 R54 R33 R180 L8 L5 L20 L53 L27 L90 L372 R562 L53 R29 R93 R40 R20 R71 L31 R843 L12 L49 R749 L30 L70 L90 L64 L84 R23 L85 R251 R53 R91 L95 L62 R93 R69 R283 R88 R29 R99 R97 R4 R38 R93 R69 L705 L32 R879 L96 R77 L61 R62 L24 L94 R33 L167 R537 L96 L13 R860 L90 L993 R86 L56 L7 L76 L13 R89 R38 L246 R88 R93 L64 L38 L571 R16 R5 R74 L43 L78 L77 L75 L26 R4 R21 R43 R18 R11 R7 L423 R23 R13 L139 R6 L56 R76 L937 L10 R47 L29 L28 R782 L25 L20 L13 R40 R40 R88 L46 L61 L85 L67 L82 R20 R84 R921 R81 L67 L47 R96 R33 L15 L18 R408 L90 L67 L5 L928 R16 L47 L76 R19 R88 L47 L302 L320 L97 L21 L13 L13 L41 L46 R79 L495 R96 R32 R72 R16 L95 R95 R28 R944 R428 L10 R40 R48 R9 R642 R71 L5 L84 L82 L65 L637 R73 L80 L20 L80 R18 R62 L25 R30 L85 L9 R285 R54 L16 R30 R36 L64 L393 L943 L646 R446 R73 L73 R16 R55 R29 L3 L397 R8 L88 L520 R50 R149 R98 R703 R89 L255 L34 R323 L70 R96 L74 R25 R44 R96 R47 R32 R7 R47 R27 L908 L9 L91 R8 L50 R50 L22 R17 R23 R21 R18 R43 R92 L92 R489 R11 L74 R80 L23 R876 L80 L79 L42 R91 L13 L33 L39 L54 L77 R12 L245 L6 L42 L52 L52 L46 L2 L97 L36 R33 L29 R57 R12 L86 R234 L69 R42 L15 R38 R16 L98 L202 L232 R48 R84 R93 R35 L10 R33 L51 R89 L889 L87 R487 R518 R82 R404 R54 R88 L46 L31 L969 R29 R72 L701 L966 L20 R86 L480 R41 L61 L96 L17 L31 L97 L52 R70 R14 R17 L40 R583 R49 R38 R62 L92 L455 L44 L56 L92 R39 L97 L403 R67 L70 R59 R79 R765 L637 L57 L44 L58 R63 L13 L83 L98 R393 L17 R51 R42 R92 R58 R21 L13 L1 L99 L13 L50 L290 L47 R46 L498 L348 R83 R53 L36 R91 L91 R69 R563 R95 R46 R27 L80 R29 L66 L69 R95 L743 R85 R49 L15 R357 L42 L924 L76 R62 R9 R886 L57 L27 R27 R57 R76 R71 R96 L862 R82 R380 R51 L44 L707 L96 L16 L40 R52 R68 L15 L11 L653 R16 L5 L89 L61 R450 L89 L11 L13 R502 R588 L17 L60 R65 L52 R37 R96 R54 L54 L9 L137 L80 R980 L907 L93 L75 R75 L36 R238 L2 R69 L69 L547 L53 L7 L573 R19 R61 L13 L92 R10 L798 R593 R88 R95 L44 L23 R71 R13 R53 R47 L7 R85 R84 L92 L57 R242 R45 L75 L25 R4 R96 R29 R19 L917 L10 L98 L23 L71 R773 R66 R496 R34 L960 R782 R353 L73 R972 L72 L909 L91 R16 L16 L95 R85 L79 R89 R97 L64 R95 R55 L283 R36 L205 R518 R68 R62 L51 R16 R56 R41 R59 R46 R963 L93 R84 R57 R43 R5 L605 R35 R518 L53 L35 R264 R96 L856 L84 R38 R77 L19 R96 L837 L40 R30 L14 L977 R32 L71 L12 R64 L52 R61 L61 R35 R65 R204 R85 L89 R659 R41 L110 L90 L478 L22 R12 L12 R773 R81 R46 R55 R584 L68 L71 R275 R80 R74 L53 R62 R66 L233 R29 R79 L879 L363 L37 L12 R82 L70 R25 L79 R39 L316 L69 L10 R10 L93 L47 L31 R71 L24 R9 L14 R95 L380 L14 R73 R21 R70 R845 L81 L573 L12 R78 R5 L21 L77 L543 R4 R78 L39 R89 R28 L77 L40 L539 R39 R93 R21 L7 R93 R65 R456 L21 R91 L991 L15 L31 L543 L11 L78 R78 R17 R103 L320 L799 R87 R99 L38 R22 R29 L59 R59 R4 R39 R15 R56 R80 R96 L76 L14 R80 R904 R16 L983 R135 L52 R56 R48 L51 L2 R181 L10 L522 R75 R10 L22 R62 R82 L40 R245 L887 R55 L328 R58 R690 L22 L72 R23 R13 R78 R84 L86 L2 R84 L34 R34 L18 L47 L86 R29 R61 R44 L24 L408 L4 L47 L36 R36 L22 L78 L91 R91 R69 L7 R351 R42 L80 L51 L24 R378 L40 L38 L9 L55 R11 R466 R4 R81 L98 R90 R10 R88 L40 L48 L2 L34 R33 L608 R11 R16 R21 R52 R56 L28 L10 R258 R27 L92 L40 R99 R23 R82 R436 L61 R13 R707 L13 R40 L13 L94 R27 L6 L8 R88 R47 R83 L10 L80 L93 R873 L708 L711 R19 R729 L982 R53 R755 L55 R48 R52 R66 R89 R42 R61 L12 R54 L34 L66 R62 L62 R75 L75 L160 L52 R68 L745 R30 R59 R18 R82 R283 R979 R97 R72 L207 L52 L72 R75 L775 L81 L19 L14 R31 R83 R26 L624 L50 R948 L930 L10 R69 R71 R46 L30 L72 R84 L67 L59 L802 R75 L730 L45 R27 L23 R68 L72 L45 L82 L73 L60 L77 R154 L17 L43 L57 R624 L28 R347 R18 L23 R3 L89 R746 R488 R31 L17 R63 R43 L719 R18 L5 R13 L380 L62 R29 R40 R260 L13 L101 R640 L26 L49 R46 L190 R93 L83 R83 L18 L96 L82 L8 R4 R33 L9 R64 R528 L342 L74 R27 L56 R93 R836 L5 L36 R41 R67 R79 R554 L788 L931 L958 L47 R3 R25 L474 L86 L36 R93 L1 R90 R54 R845 R4 R7 L98 L13 R19 R92 R55 R45 L64 L541 L51 L30 R86 R75 R89 L64 R3 R97 R87 L86 R99 L79 L21 L74 R25 R67 L48 L70 R534 L26 R75 R359 R66 L70 R62 R17 L98 R43 R38 L94 L21 R78 L63 R14 L14 L68 L32 R80 R20 L77 L57 L23 L443 R211 L204 L53 R44 L58 R77 L61 L734 L7 L68 L46 L21 R294 R26 L94 L6 R93 R60 R546 R45 L87 R267 L34 L5 L88 R3 L648 L52 L605 R5 L32 L918 R568 R10 R772 L77 L26 R3 L75 R75 L16 L84 R58 R74 L30 R429 R29 R2 R60 L22 R3 R97 R79 L11 R75 L43 R56 L56 R62 L862 R76 L8 L566 L2 L81 R28 L86 R39 R891 R71 R54 L99 R83 R47 L6 R759 R65 L913 L98 L26 R134 R90 R56 R92 R85 L55 R970 R70 L94 R24 L23 R40 L17 R62 R38 L282 L560 R42 L55 L99 R54 L912 L56 L58 L74 L10 R61 R21 L72 L67 L94 L101 R662 L581 L4 L75 L59 L94 L87 R1 L56 R55 R91 L91 L398 R82 L84 R3 R97 R32 R2 R60 L9 R337 R78 L668 R98 L651 R562 R34 L94 L981 R88 R12 L887 R22 R567 R98 R68 L68 R8 L79 R18 L747 L355 L3 L24 L18 L10 L27 L137 R62 L38 L7 L1 L16 L26 L60 R112 R93 R556 R12 R388 L56 L445 R24 L924 L64 R78 R85 L99 L457 R89 L89 L66 R60 L80 L18 L91 L81 L14 R47 L20 R20 L14 R14 L72 L407 L79 R43 L13 L90 L16 R51 L924 L33 L40 R80 L551 R107 R44 L54 R54 L33 R923 R241 L116 L93 L22 R225 L64 L60 L504 L44 R55 R23 L31 R32 R28 R987 L38 L61 R552 L22 L38 L794 L46 R48 R98 R254 R155 L45 R588 R1 R10 R70 R56 L435 R40 L2 R606 R64 L8 L97 R39 L42 L120 L180 R410 R66 R39 R99 L14 R9 R70 L83 L224 L649 R77 L7 R7 L41 R16 R38 L42 R48 L53 R47 L13 L29 L24 R78 L22 L279 L690 R99 L46 L42 R724 L369 R35 L899 L236 L71 L29 R17 L17 R37 L37 L482 R707 R5 R14 L13 L29 R98 R303 R61 L64 R78 L57 R79 L146 L24 R23 L24 L29 L20 L97 R217 L226 L22 R6 L758 L87 R87 R4 L4 L19 R6 R21 R313 L621 R65 L965 L71 L29 L66 R889 R33 R91 R45 L992 R65 L8 R443 R16 R84 L93 R93 R82 L82 R99 L62 R48 L20 L65 L52 L32 R84 L59 L41 R963 R36 R53 R48 L39 R39 L387 L13 R69 L69 R78 R1 L979 L75 L310 R885 R1 L63 L38 L28 R173 L32 L84 R866 L59 R64 L21 R18 R3 R1 R90 R9 L923 L77 R473 L86 L531 R62 R669 L85 L202 L636 R840 R39 L43 R59 L41 R72 R210 R13 R887 L27 R27 L74 L58 R9 L77 R57 R43 L64 L63 L573 L149 L777 L70 L83 L921 L360 L608 R96 L25 R18 L24 L97 R20 R94 L169 L84 R39 L14 L86 R778 L78 L45 L72 R69 R5 R17 R64 L473 R418 L83 L63 L86 R65 R5 R79 R33 L33 R37 L28 R91 L84 R81 L84 R487 R82 R18 R578 L990 L88 L89 R89 L33 R33 L80 L231 R88 L77 R770 R30 L83 L83 L75 L89 R599 L506 L608 L18 L37 L42 L27 R43 R26 L90 L10 R74 R7 R19 L25 L96 R78 L60 R103 R57 R46 R17 L747 R44 L338 L302 R23 L1 R75 L27 R52 L99 L51 R34 L183 R803 L86 R94 R66 L77 R963 L603 R140 L877 L4 R28 L83 L764 R72 L92 L80 L39 L88 L47 L70 R9 L97 R77 R8 R46 L30 L69 R59 R19 L58 L27 L93 R172 L273 R50 L59 R71 L44 L17 R92 L92 R40 R28 L63 L6 L92 L7 R15 R685 L999 L1 L20 R4 L958 R98 R76 L821 L62 R483 L452 L48 L22 R42 R51 L71 R80 R20 L69 L22 L42 R31 R2 L46 R25 R45 L70 R67 L15 L506 R10 L224 L86 L55 L45 R57 R51 L85 L91 R268 R85 R15 R23 L97 R68 L537 R43 R40 R65 R308 L2 L11 L80 R80 R347 L26 L25 R72 L63 R22 L27 L90 L10 L89 L11 R958 L94 R24 L106 R78 L26 R66 L13 L12 L75 L157 L597 L65 L352 R16 L53 R95 R105 R98 L1 R73 R38 L322 L75 R54 L49 R66 R26 L758 R64 R32 L38 L97 R97 R14 R65 R23 L76 R72 L31 R19 R14 R81 L81 L72 L29 L99 R76 L986 L87 L3 R35 R48 R17 R97 L50 L63 L94 L50 R656 R4 L10 L90 L972 L28 R340 R51 R909 R152 R28 L42 R362 R56 R56 L63 L61 R19 L920 R24 L497 R86 R50 L16 L66 R43 R31 R358 R96 L596 R22 R44 L26 R60 R34 R58 L262 R29 R55 L14 L84 R91 R88 R5 R559 L41 L718 L51 L53 L96 L53 L47 R69 L69 L20 R43 L355 L68 R177 R51 R56 L84 L88 R61 L43 L30 R54 R188 R758 R78 R722 L74 L26 L89 R162 R696 L69 L56 R56 R32 L32 L9 L42 R933 L81 R46 L52 L43 L52 R98 L26 L35 L20 L40 R53 L30 R585 L29 R433 R52 L353 L86 R80 R23 R59 R28 R8 R38 L234 L4 L42 L950 L68 L26 R75 L89 R79 L79 R99 R64 L14 L59 L83 L86 L70 R49 R35 L37 L98 R76 R77 L18 R99 R25 L15 R32 R63 R3 L77 L192 L96 R73 L95 L39 L16 L79 R79 L537 R37 L49 L10 R167 L97 L37 R7 R19 R17 R83 L2 R2 L28 L72 L24 R95 R529 R69 R465 L91 R69 R88 L61 R561 R17 R214 L31 R62 L87 L968 L7 R10 R25 L58 R909 R82 R32 R92 L792 L30 R30 L507 R468 R39 R60 L41 R81 R38 L338 R101 R83 L84 R58 R92 R732 L95 L85 R98 L93 R93 L34 R34 R582 L44 L588 R50 L469 R69 L215 R415 R91 R77 L953 R78 L17 L25 L18 R67 L68 R68 R43 R2 L52 L61 R68 R37 R68 L31 R478 R631 L83 R60 R12 L15 L57 L6 R18 R54 R64 L30 R88 R83 L71 L64 L3 L33 R88 R12 L79 L27 L23 L71 L61 L397 L42 R97 R4 L1 R346 R811 L57 R11 R89 R51 L51 R8 R92 L52 R52 R25 R62 R823 L64 L27 L897 L22 R80 R63 L97 L40 R993 L95 L43 L20 L40 R99 R96 L54 L367 R872 L76 R11 R1 L112 L53 L98 R7 L427 R352 L97 R32 L587 L34 L85 L13 R32 R1 R48 L38 R48 L2 L2 L357 L98 R92 L28 L39 R775 L20 R66 R2 L48 R15 R85 L46 R646 L97 R59 R39 L39 L96 R7 R27 L75 R75 L56 R52 R4 L69 R88 R62 R80 L76 R15 L146 R46 R28 R72 L80 L35 R14 L99 L45 R96 R29 L78 L902 R30 R82 L586 R64 L90 L54 L62 R16 R724 R76 R19 R81 R2 R798 R49 L49 L851 R51 R84 L8 L76 L40 R940 R86 R25 L55 L65 R9 R96 L890 R16 L27 L95 R90 L90 L96 L4 L9 R66 L831 L152 L37 R43 L217 L63 L22 R22 R550 L86 L66 L98 L646 R724 L472 L6 L11 R42 L94 L68 L8 L56 L43 L3 L61 L98 L43 R18 L784 L8 R17 L68 R968 R38 L41 R98 R37 R57 R211 L71 R119 R22 L70 L3 R84 L81 L45 R45 L3 R3 L37 R84 R57 L4 L58 L22 R57 R15 L909 L87 L170 R130 L56 R219 L517 L72 L172 R73 L69 R41 R55 R342 L254 R26 R54 R29 R68 L35 L695 L65 L31 R26 R2 R62 R54 L41 R47 R95 L79 R335 R86 L84 L56 L377 L67 R28 L28 L23 R35 L267 R33 R22 R523 R45 L968 L966 R70 R25 L1 R306 R66 R19 R593 R88 R29 R71 L31 R631 R65 L65 L14 L93 R85 L778 R1 L770 L431 R62 R95 R932 L53 L224 R96 L93 R216 L79 L44 R498 L6 L19 R84 L345 R862 R818 L535 R5 L60 R485 L60 L35 R93 R807 R52 R48 L68 L68 L64 R84 L284 L84 L23 R7 L94 R94 R93 R26 L41 L14 L64 L12 L88 L41 L46 R87 R38 R53 R806 L97 L41 L830 R52 L81 R26 L59 L53 R87 L246 R45 R78 L34 L44 R90 L47 L387 R38 R88 R76 R863 R60 L3 L78 L510 L90 R31 L431 R93 L91 L83 R81 R594 R6 R92 R8 R64 R412 L76 L51 R51 R69 L69 R31 L81 L96 L3 R49 R73 R55 L28 R33 R61 R433 L348 R63 L119 L23 R34 L7 R573 R87 R13 R88 L31 R43 R60 R67 R73 L15 R15 L68 R14 R50 R4 R199 L63 R80 L77 L65 L274 R52 R25 L77 R43 L68 L75 L648 R48 L45 R45 L45 R46 L266 R65 L87 R87 L79 R83 L395 L9 L10 R685 L533 L14 L46 R56 R173 L11 R24 R76 R57 R85 R58 R539 L18 R7 R20 L11 L98 R61 R44 R956 L41 L39 R71 L54 R89 R65 L18 R82 L24 R69 L41 R41 L6 R98 R9 L120 R26 R393 L529 L33 R26 R64 L86 R147 L68 L25 R4 L46 L54 R843 L43 L275 L325 L53 L93 L54 R86 R14 R6 L6 R77 L44 L33 L90 R90 L17 L67 R84 R748 L48 L9 L848 R72 R45 R998 L63 L43 R306 R42 L46 R26 L80 R29 R13 L42 L49 L51 L181 L76 L34 L9 R17 L3 R92 L9 R684 L619 R68 R70 R71 R39 R90 R78 L78 L54 R44 L90 L62 L65 L18 R27 L50 R82 R4 L62 R64 R80 R14 R486 R59 L623 L73 R55 L13 R95 L86 L94 L58 L62 L41 R83 R47 L195 L16 L98 R69 L90 L59 L329 R29 L530 L699 R18 L435 R46 L51 L78 L61 L67 R25 R86 L87 R32 L24 L75 R530 L96 R66 L17 R16 L14 L85 L8 R408 L85 L59 L12 L158 L3 R66 R76 L25 L58 R258 R97 L97 L54 L54 R8 L92 L8 R83 R55 R96 L39 R64 L59 R62 R638 R626 L586 R360 R464 L66 L30 L570 R722 L820 R14 L25 L503 R571 L57 R52 R36 L89 R56 L55 R57 R943 R50 L87 L4 L44 R73 R12 R67 L67 R89 R11 R99 L99 R29 L29 R649 R551 L56 L44 R62 R9 L79 R835 L107 L25 R38 R786 L59 R40 R99 L92 L247 L60 R24 L25 R4 R97 L74 R33 R68 L27 R66 L44 R78 R953 L10 R47 R93 L449 R48 R19 R25 L56 R54 L992 L32 L51 R866 R85 L37 L68 R19 R46 R82 L80 R95 R76 R42 R25 L61 L39 R31 R28 L85 L74 R36 L36 L638 R99 R22 L60 R89 R88 L50 L50 L23 R8 L85 L50 R75 L25 L30 R13 R34 L317 R48 R31 L79 R56 L57 R12 L611 R97 L38 R41 R25 R66 L91 L865 L836 R35 R723 L57 R92 L59 L45 R37 L26 L390 R79 L88 L42 L41 L17 L85 L19 L34 R38 L3 R3 R64 L64 L705 L22 L72 L46 R91 R554 L61 L39 L489 R227 L94 L144 L76 L25 R121 L20 R1 R612 R61 R648 R87 L24 L22 R637 L38 R81 R45 R33 L370 L51 L45 L86 R43 L78 L73 R39 R361 L61 R424 L62 R62 L89 R99 L834 R80 R20 L77 L45 L78 R76 L41 R533 L68 R10 R90 R99 R67 L74 L21 R56 R12 R34 L673 L21 R54 R73 R92 L498 L88 L437 R50 L27 L6 L21 L2 R31 L96 R496 R30 L67 L63 R410 L62 L41 R14 L21 L331 R31 L14 R14 R95 R48 R57 L92 L75 R67 R13 R6 R981 R282 L76 L744 L62 R19 R81 L23 R95 L53 L735 L96 L238 L49 L57 L44 L28 R15 L87 R13 L13 R15 L15 R28 L33 L22 L912 R867 R592 R80 L66 L811 R68 L44 R4 L51 R78 R34 L18 L594 R813 L413 L584 L783 R89 L682 R11 L51 R70 R30 R944 L15 R71 R43 R35 L4 L14 R995 R449 R796 R52 L52 R53 L15 R62 R421 L44 L78 L99 L75 R58 L71 L31 R64 R55 R81 L81 L35 R93 R66 R865 R1 R724 R16 L11 L519 L4 R31 L339 R12 R97 L97 L41 R951 L50 R40 R351 L79 L22 L50 R22 L39 L83 R3 L141 R5 R22 R363 R48 L12 L783 L15 L51 L39 L93 R93 L82 R54 R2 R31 L71 L34 L88 R96 L14 L94 R80 L80 L48 R50 R19 R27 L75 R527 L529 R994 L65 L2 L58 L40 L428 R30 L17 L85 L272 R337 R71 L36 R39 R51 R93 L15 R81 L29 R80 R51 L51 L28 L661 L88 L39 R581 L97 R32 R6 R94 L95 L5 R59 R56 R85 R839 R61 L940 R5 L552 R83 L96 R57 L259 R56 L54 L98 R265 R33 R64 R80 R309 R756 L64 L10 L20 L258 L233 R76 R58 R42 L58 R63 L96 R24 R636 R437 R19 R23 R604 L70 R55 R26 L2 R39 R26 L50 L76 R65 L65 R83 L11 R46 R26 R28 R28 R91 R24 R66 R603 R26 R90 L88 L212 L65 L76 R84 R51 L257 L39 R2 L59 L970 L36 R51 R14 R457 R447 L544 R105 R185 L22 L628 L18 L85 L119 L64 R44 R42 L269 L86 R55 R13 L52 R39 L22 R4 R60 R42 L74 L10 R367 R33 L44 L73 L79 L4 R33 L18 L15 R52 L552 R44 L144 L28 R94 R97 R37 L909 L991 L563 L90 R619 R98 L263 L55 R733 L14 R41 R2 L988 L20 L29 L27 L23 L83 R262 R85 R65 L5 R955 R99 L99 L81 R90 R16 L73 R48 R11 R63 R76 L17 L34 R201 L722 R522 L30 R27 L49 L43 L5 L19 R46 L44 L579 R828 R68 L1 R672 L4 L48 R833 L23 R52 L68 R33 L77 L569 L14 L559 L25 R83 L24 R95 L356 R7 L7 R195 L33 L930 R68 R81 R19 L23 L77 L2 L736 R38 R63 R81 L59 L43 L40 L95 L27 L80 L13 R65 R283 L14 L921 R59 R1 R55 L93 R78 L2 R95 L80 R38 R38 L34 R64 R34 R47 L58 R75 R29 R454 L78 L2 R80 R116 R81 L39 L58 L39 R39 L83 L17 L30 R30 R82 L90 R46 L590 R52 L62 L38 R14 R508 L26 L50 R89 L25 L10 R831 R225 L56 R94 R75 R31 L37 R37 L75 R71 R37 L52 R19 R14 R86 L70 L819 R87 L305 R86 L79 L39 R81 R58 R29 L24 L53 L898 L83 R355 R74 L18 L81 L1 L50 L50 L223 R15 R8 R787 L87 L75 L37 L943 L55 R63 L53 L269 R2 L1 L32 L42 R62 R67 L24 L338 L25 L61 R61 L36 R636 R43 R57 L4 L85 L63 L48 R497 R3 L57 L52 R51 L68 L74 R2 R866 R32 R545 R124 L12 L6 L13 R62 L47 L3 L847 L69 L24 L10 R68 R38 R962 L47 L121 R90 R35 L63 L33 R5 L34 R308 R57 L54 L76 R56 R9 L81 R212 R6 R48 L44 L141 R13 R87 L2 R941 L39 L46 R158 L95 R35 L89 L63 R81 L850 R64 R5 L99 R668 L69 L748 L652 L59 R94 L74 L61 R5 R691 R4 R19 L535 R16 R99 L99 R12 L431 R29 L218 R73 L56 R91 L593 L55 L40 L82 R99 L29 R39 L819 L85 R85 L3 R34 R79 R70 R17 L80 L69 R98 R64 R70 R5 L5 R93 R75 L1 R120 L88 L14 R15 L61 L539 R258 R22 L80 L15 R40 L25 R5 R62 L21 R50 L65 R95 R74 L38 L62 L72 R94 L953 R22 R90 L81 R97 R172 L38 R5 R164 L58 R7 R55 R763 R33 R65 L910 R45 L95 L5 L5 L62 R67 R53 R81 L94 R10 L26 L83 L865 R42 R36 R12 L25 R759 L8 L77 L15 L15 R15 L99 R16 R68 L85 L97 R950 L88 L44 L21 L65 R465 L88 R38 L1 L5 R11 R20 R86 L28 L33 L97 L3 L738 R38 R78 L771 L79 R821 R51 R62 R19 R473 R378 L32 L87 R47 R42 L294 L78 L25 L53 L93 L259 L83 R86 R61 R67 L11 R80 L19 R19 R81 R71 L30 L22 L32 L66 L8 L10 L961 R77 R8 R3 L61 R42 R408 L27 L113 L70 R10 L252 R88 R64 R41 L665 R39 R38 L78 L6 L239 L30 R637 L87 L42 L35 L16 R909 R97 R89 R37 L289 R36 R350 L9 L86 R68 R13 R28 L85 R85 R95 L95 R51 L24 L455 L49 R77 R61 R39 R65 R35 L96 L50 R446 R72 R28 L29 R17 R268 L456 R148 R829 L77 R543 L97 L13 R25 R22 R53 R63 L9 R13 L10 R10 R21 L89 R77 R6 R15 R70 R9 L38 L38 L414 R55 L517 L84 L73 R28 R820 L87 L17 L44 L59 R7 R752 L32 L68 R34 R64 R531 R30 R12 L278 R7 R275 L59 R792 L98 L26 L46 R13 L33 R82 L76 L67 L66 L91 R63 L26 R563 L65 L35 R683 R64 L15 R8 R788 L328 R41 L6 L15 L220 R37 L837 R18 L717 R27 R72 L56 L431 R81 L94 L18 R92 R23 R94 L18 L73 R77 L29 L10 R62 L10 R53 R88 L61 R30 R179 R77 L266 L83 R55 R9 R29 L2 R2 R21 L71 L50 L25 R25 L78 L99 L71 L54 R2 L96 L65 R53 L92 L1 R43 R58 L40 R75 R65 L958 R57 L322 R10 L17 L25 L37 L308 R653 L5 L16 L285 L47 R38 R24 L62 L91 R95 L36 R57 R75 R205 R48 L52 L35 L14 R1 R73 R27 R465 L18 R25 L25 L370 L268 R51 L52 R39 L856 L74 R834 L28 L80 L96 R45 R55 R72 L10 L40 R84 L901 L105 L81 L62 R85 L42 R80 R7 R13 R91 L91 L72 R14 L87 R16 L71 R59 L5 R66 L78 R14 L74 L82 R440 R638 R36 L72 L3 R86 L13 L50 L863 R21 L54 L66 R90 L67 R746 L69 R37 R63 R87 R40 L880 L47 L63 L886 L77 L67 R38 R32 R72 R51 L86 R60 R30 R896 R91 L891 L84 R584 R98 L98 L89 L54 L557 L282 L87 R48 R557 R3 L52 L20 R533 R33 R198 R82 R87 L86 L14 R48 L736 L684 R29 R5 L594 L68 L49 R36 R20 L7 L70 L7 L223 L42 L358 R49 L582 R33 L59 R59 L52 R52 R660 L33 R68 R82 R23 R27 L96 R91 L22 L307 R7 R88 R69 R57 R86 L213 L891 R40 L30 L73 R67 L54 L146 L53 L47 R85 R15 R97 L1 L167 R71 L30 L71 L95 R11 R85 R45 L45 L12 R90 L551 L595 R69 R99 R756 R96 L73 R965 L62 L82 L36 L64 R66 L30 R64 L83 R80 L59 R62 R410 R67 L377 L10 R10 L701 L99 L79 L561 R65 L25 R24 L72 L52 L42 R42 R63 L67 L96 L65 R17 L852 L63 L79 R86 R56 R49 R51 L27 L39 R30 R32 L2 R134 L57 R29 R96 R24 L30 R310 R58 L89 L727 R956 L98 R116 L221 L16 R21 R31 R25 R344 R67 R66 R67 R48 R52 R57 L9 L548 L68 R83 R988 L264 R62 R67 R32 L96 R96 R468 R69 R43 R31 L9 R98 L10 R10 L16 L84 L746 R72 R62 R412 L679 L21 L82 L89 R23 L552 R7 R749 L36 L693 L27 L57 R98 L91 L128 R278 R84 L79 L65 R49 R911 L77 R867 L76 L14 L66 L534 L96 L68 R22 R808 R174 L40 R93 R22 L15 R816 R584 L50 R950 L9 R69 R40 L37 L85 L615 L63 L24 L76 R8 R92 R12 L74 L92 R15 L7 L84 L24 R68 R94 R55 R37 L988 R88 R13 L42 R929 L25 L875 L242 L59 L89 L197 R87 L54 R43 L845 L30 R3 L17 R77 L53 L24 L72 L84 L12 L99 R45 R85 R27 L90 R868 R98 L955 R89 L74 L26 R47 L299 R52 L14 R75 R406 L78 L27 R37 L4 R83 R48 R853 L79 L931 R89 R42 L29 R29 R66 R25 R68 L8 R220 R29 R55 L15 L61 R56 R298 R667 L86 R54 L92 L91 R839 R638 L25 R82 R39 R66 R62 L86 L672 L76 R34 L2 L84 L78 R39 R70 R307 L557 L3 L66 R9 R479 R11 R85 R92 L88 R343 R510 L53 L773 L27 L48 R56 L95 R48 L60 R41 L95 R53 R87 L87 R6 R45 R49 L53 R4 R71 L86 R64 L79 L11 L37 R27 R58 R42 R29 L29 L60 L40 R76 R57 R67 R85 R11 R65 L61 L88 L97 L15 R46 L22 R13 R63 L7 R7 R31 L43 R24 R3 L15 R9 R91 R38 R4 L20 R20 L23 L37 L10 L44 R11 L49 L4 L28 L47 R45 L23 L44 R30 L30 L43 R20 L19 L49 R41 L41 L9 L42 L35 L19 R39 L2 R44 R7 L36 L7 L18 R15 R19 R45 L1 L49 L37 L14 L41 L34 R26 R46 L6 R16 L1 R47",
  });

  console.log(prob_1_1(DATA.test));
  console.log(prob_1_1(DATA.case));

  console.log(prob_1_2(DATA.test));
  console.log(prob_1_2(DATA.case));
})();

Here’s some Prolog solutions to Day 1, which are all different:

Day 1 is a maths puzzle. Is maths relational? It can be, e.g.:

In clpfd:

?- A #= B + 1.
B+1#=A.

In clpBNR:

?- { A == B + 1 }.
A::real(-1.0Inf, 1.0Inf),
B::real(-1.0Inf, 1.0Inf).

None of the above 4 solutions to Day 1 start with numlist(0, 99, L) and then treat the dial as a sliding window over that list, with append. Which sounds like a relational approach, although probably inefficient. Because maths is intuitively the easy method :slightly_smiling_face:

I expect in the 12 days there will be better examples…

1 Like

@brebs I said “functional”, not “maths”: indeed, AFAICT (I have not done any careful analysis, please feel free to shoot), all those solutions (thank you for the links) are essentially like mine, “functional” as opposed to “relational” in terms of programming paradigms, just some are more efficient / synthetic / clever than others… But of course I am just chasing general principles.

Tongue-in-cheek:

All maths is relational. Expressing A = B + 1 is purely (in Peano arithmetic, for natural numbers):

plus1(0, s(0)).
plus1(s(P), s(s(P)).

General case:

?- plus1(P, P1).
P = 0,
P1 = s(0) ;
P = s(_A),
P1 = s(s(_A)).

This works in Prolog when neither A nor B are defined, is that not excellent? :grinning_face:

So? What’s wrong with a Prolog predicate being basically a function, when that is all that is needed at the time?

Predicates can have the potential to be usable in all directions, but for these Advent challenges we only care about the question space, i.e. there’s exactly 1 question per gold star to be answered.

Anyway, on to day 6, which looks at first glance like a good use of DCG and transpose/2 …

I chose to document my AoC progress here: @frank-schwidom.bsky.social on Bluesky

And Just in case someone is interested in my AoC code: AdventOfCode/2025 at master · schwidom/AdventOfCode · GitHub .

1 Like

Day 7 was funny !

I was struggling to get the small data solution of part 1, with tabling.

Then I quickly wrote part 1 in Dart, and once unlocked part 2, LOL, the answer for the small data was the same I got (wrongly) from tabled part 1.

So, tried with the large data, and got the puzzle solved !

1 Like

Here is a solution for the day 1 part 2 using clpfd + foldl:

  • rotate(Direction-Distance, State-Count, NewState-NewCount) is fully pure, and relates the state and count of passing by zero before and after applying a rotation.
    • the implementation is not fully deterministic for performance reason, where I pattern match on the direction to choose the correct formula
    • this means you can apply a rotation with arguments in any modes

Is this Prolog-ish/relational enough for you ? :slight_smile:
Or is your “functional” a qualifier for the successive application of rotation, i.e. foldl ?

Spoiler implementation
lines(Pairs) -->
    sequence(line_, Pairs).
line_(Direction-Distance) -->
    direction(Direction), number(Distance), eol.
direction(-1) --> "L".
direction(1) --> "R".

rotate(Direction-Distance, State-Count, NewState-NewCount) :-
    Rotation #= Distance // 100,
    Rest #= Distance mod 100,
    OverFlowState #= State + Direction*Rest,
    NewState #= OverFlowState mod 100,
    pass_by_zero(Direction, State, OverFlowState, PassByZero),
    NewCount #= Count + Rotation + PassByZero.

% (       (State #> 0 #/\ OverFlowState #=< 0)
%     #\/ OverFlowState #>= 100
% ) #<==> PassByZero,
pass_by_zero(-1, State, OverFlowState, PassByZero) :-
    % left rotation
    % (State #> 0 #/\ OverFlowState #=< 0) #<==> PassByZero
    StatePositive #= (State + 99) // 100,
    OverFlowNonPositive #= (-OverFlowState + 100) // 100,
    PassByZero #= StatePositive * OverFlowNonPositive.
pass_by_zero(1, _, OverFlowState, PassByZero) :-
    % right rotation
    % OverFlowState #>= 100 #<==> PassByZero
    PassByZero #= OverFlowState // 100.


main(Count) :-
    once(phrase_from_file(lines(Pairs), "input-1.txt")),
    foldl(rotate, Pairs, 50-0, _-Count),
    format("Count ~d~n", [Count]).
2 Likes

I was talking about the programming paradigms: logical vs functional vs imperative, which we use to think about and approach problems; and these exist regardless of the language, though of course, depending on the approach, some languages are more suited than others.

That said, IMO your solution is along the same lines as the other solutions, just some are more efficient (etc.) than others, e.g. we don’t need to pre-parse the whole thing (hint: “iterators”)… and the more we reduce it to just a solution to the given problem, the more it’s just about “aggregating a simple computation over the input”, which, modulo an anyway here trivial parsing of the input, is indeed inherently a “functional” operation (I’d say).

Anyway, I do not have clear ideas myself, but I suppose what I am after is a logic programming way of thinking about the problem itself: what would that be (in general)? Maybe it has something to do with thinking about a more general version of the/a problem? Or, on the contrary, maybe some problems, as in particular the problems from Day 1, are just not really amenable to a logic programming “framing”?

Hopefully of interest: https://stackoverflow.com/questions/8297574/difference-between-logic-programming-and-functional-programming

The Advent of Code questions:

  • Ask just 2 precise questions (part 1 and part 2) each, and don’t care about Prolog’s generality, i.e. potentially being capable of answering further questions about the problem space quite easily
  • After answering the questions, what seems to matter is:
    • Code elegance and shortness (although I would add readability to this list) - which partly favours more popular languages which have more code libraries available
    • Performance (milliseconds) - which favours languages which have had more effort put into their compilers

In the repos mentioned in this thread, I think there’s at least one elegant Prolog solution to each Advent question so far :grinning_face:

Sure, and I am not saying otherwise. OTOH, you keep missing the point of my question here, or should simply admit you are not interested: it is indeed a side question, but let it be please. [Actually, it’s a meta-question: what are we even doing here? For the researcher, or the teacher, or just the conscientious programmer, I suppose.]

Well, I have only skimmed through the other solution but the specificity of mine is that it is logically pure, can be used in any direction/mode.
And concretely, for me, that is kind of the specificity of the logical programming paradigm:

Make your code work in any mode/direction

And that implies thinking about the broader relation that underpin the problem you are trying to solve.

If I could list the stereotypes for each paradigm:

  • imperative: give order to computer one after the other
  • functional: hm, mutation is bad, I don’t want to deal with state
  • logical: nice, but what if I could run that function in reverse ?

The topic of this thread, that I started, is “Advent of Code 2025”.

Please start your own thread, for whatever your question now is, or maybe check the Philosophy sections of Reddit :wink:

Back on topic - just starting Day 8 (I’m probably slipping behind, since these questions are not getting easier), and it’s screaming clpfd :grinning_face:

… or clpBNR.

I see, though that I have called “relational” and I do not think it exhausts what logic programming is: though I cannot exactly say what logic programming is, which is why I am asking. :slight_smile:

That said, just your maths is reversible, not the program itself: namely, you cannot enumerate inputs, i.e. you do not have a main(?Data, ?Count)