! Copyright (C) 2023 Fred Alger ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays assocs calendar db db.sqlite db.tuples db.types documents fry io.pathnames kernel math math.parser namespaces peg.ebnf prettyprint sequences sequences.deep sequences.extras splitting strings ui.clipboards unicode urls vectors webbrowser ; IN: advent2023 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! database for puzzle inputs ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TUPLE: puzzle-input id day stage input ; puzzle-input "PUZZLE_INPUTS" { { "id" "ID" +db-assigned-id+ } { "day" "DAY" INTEGER } { "stage" "STAGE" INTEGER } { "input" "INPUT" VARCHAR } } define-persistent : inputs-database-path ( -- path ) "work/advent2023" resource-path "advent2023.sqlite" append-path ; : ( -- db ) inputs-database-path ; : with-puzzle-input ( quot -- ) '[ _ with-db ] call ; inline : save-input ( day stage input -- ) puzzle-input new swap >>input swap >>stage swap >>day [ puzzle-input ensure-table insert-tuple ] curry with-puzzle-input ; : get-input ( day stage -- str ) puzzle-input new swap >>stage swap >>day [ puzzle-input ensure-table select-tuple input>> ] curry with-puzzle-input ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! interactive tools ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : clip> ( -- str ) clipboard get-global clipboard-contents ; : (advent-now) ( -- day ) now day>> number>string ; : (www-path) ( -- url ) "https://adventofcode.com/2023/day/" (advent-now) url-append-path ; : (inputs-path) ( -- url ) "https://adventofcode.com/2023/day/" (advent-now) "inputs" url-append-path url-append-path ; : open-www ( -- ) (www-path) open-item ; : open-input-www ( -- ) (inputs-path) open-item ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! day 1 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! one line of input is "abc3oaeu9aoejud9ab" ! find first and last digit (there may be only 1 digit), that's the checksum ! sum up all lines and that's the calibration value : .d1-first-digit ( line -- n ) [ digit? ] find nip ; : .d1-last-digit ( line -- n ) [ digit? ] find-last nip ; : 2num ( ch ch -- num ) 2array >string string>number ; : .d1-line ( line -- val ) [ .d1-first-digit ] [ .d1-last-digit ] bi 2num ; : .d1-run ( input -- ) string-lines [ .d1-line ] map-sum . ; : words>nums ( str -- str ) EBNF[=[ one="one" => [[ drop CHAR: 1 ]] two="two" => [[ drop CHAR: 2 ]] three="three" => [[ drop CHAR: 3 ]] four="four" => [[ drop CHAR: 4 ]] five="five" => [[ drop CHAR: 5 ]] six="six" => [[ drop CHAR: 6 ]] seven="seven" => [[ drop CHAR: 7 ]] eight="eight" => [[ drop CHAR: 8 ]] nine="nine" => [[ drop CHAR: 9 ]] word=one|two|three|four|five|six|seven|eight|nine all=(word|.)+ ]=] >string ; : words>nums-reverse ( str -- str ) EBNF[=[ one="eno" => [[ drop CHAR: 1 ]] two="owt" => [[ drop CHAR: 2 ]] three="eerht" => [[ drop CHAR: 3 ]] four="ruof" => [[ drop CHAR: 4 ]] five="evif" => [[ drop CHAR: 5 ]] six="xis" => [[ drop CHAR: 6 ]] seven="neves" => [[ drop CHAR: 7 ]] eight="thgie" => [[ drop CHAR: 8 ]] nine="enin" => [[ drop CHAR: 9 ]] word=one|two|three|four|five|six|seven|eight|nine all=(word|.)+ ]=] >string ; ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! day 2 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : .d1.2-line ( line -- val ) [ words>nums .d1-first-digit ] [ reverse words>nums-reverse reverse .d1-last-digit ] bi 2num ; : .d1.2-run ( input -- ) string-lines [ .d1.2-line ] map-sum . ; : d2.1-run ( -- ) 2 1 get-input . ;