Skip to content

Instantly share code, notes, and snippets.

@markjenkins
Last active December 10, 2022 08:47
Show Gist options
  • Save markjenkins/46ae14eb8ac3cc3b16a736c353d629be to your computer and use it in GitHub Desktop.
Save markjenkins/46ae14eb8ac3cc3b16a736c353d629be to your computer and use it in GitHub Desktop.
Advent of code 2021 in Python and Guile Scheme https://adventofcode.com/2021/
#!/usr/bin/env python3
EOFDEPTH = -1
def read_depth_line():
try:
line = input()
return int(line)
except EOFError:
return EOFDEPTH
if __name__ == "__main__":
prev = read_depth_line()
count = 0
while EOFDEPTH != prev:
cur = read_depth_line()
if cur > prev:
count += 1
prev = cur
print(count)
#!/usr/bin/env guile
!#
(use-modules (ice-9 rdelim))
(define (read_depth_line)
(let ((line (read-line)))
(if (eof-object? line) -1 (string->number line))))
(define (recursively_sum_increases count prev cur)
(let ( (newcount
(if (> cur prev)
(+ count 1)
count) ) )
(if (= -1 cur)
newcount
(recursively_sum_increases newcount cur (read_depth_line) ) ) ) )
(define first_depth_line (read_depth_line))
(define second_depth_line (read_depth_line))
(display
(recursively_sum_increases 0 first_depth_line second_depth_line) )
(newline)
#!/usr/bin/env python3
from collections import deque
from d01p1 import EOFDEPTH, read_depth_line
if __name__ == "__main__":
q = deque( [read_depth_line() for i in range(3)] )
count = 0
depth_sum = sum(q)
while True:
new_val = read_depth_line()
if EOFDEPTH==new_val:
break
q.append(new_val)
new_depth_sum = depth_sum + new_val - q.popleft()
if new_depth_sum > depth_sum:
count += 1
depth_sum = new_depth_sum
print(count)
#!/usr/bin/env guile
!#
(use-modules (ice-9 rdelim))
(define EOFDEPTH -1)
(define (read_depth_line)
(let ((line (read-line)))
(if (eof-object? line) EOFDEPTH (string->number line))))
(define (q_from_parts incoming outgoing)
(cons incoming outgoing) )
(define (new_q_from_list l)
(q_from_parts '() ; incoming items
l )) ; outgoing items
(define q_incoming car)
(define q_outgoing cdr)
(define (q_empty q)
(and (null? (q_incoming q))
(null? (q_outgoing q)) ))
(define (deque q)
(if (null? (q_outgoing q) ) ; if there are no outgoing items
;; then rebuild the queue by using all the incoming items as out
(deque (q_from_parts '() (reverse (q_incoming q) )))
;; otherwise use outgoing, return a pair of popped item and
;; new q
(cons (car (q_outgoing q))
(q_from_parts (q_incoming q) (cdr (q_outgoing q)))) ))
(define (enque q i)
(q_from_parts (cons i (q_incoming q))
(q_outgoing q) ))
(define initial_depths (list (read_depth_line)
(read_depth_line)
(read_depth_line) ) )
(define initial_sum (+ (car initial_depths)
(cadr initial_depths)
(caddr initial_depths) ))
(define (recursively_count_window_increases sum q count)
(let ((newvalue (read_depth_line)))
(if (= EOFDEPTH newvalue)
count
(let* ((deque_result (deque (enque q newvalue) ))
(new_q (cdr deque_result))
(oldvalue (car deque_result))
(new_sum (+ sum newvalue (- oldvalue))))
(recursively_count_window_increases
new_sum
new_q
(if (> new_sum sum) (+ 1 count) count)) ))))
(write-line (recursively_count_window_increases
initial_sum
(new_q_from_list initial_depths)
0 ) )
#!/usr/bin/env python3
from sys import stdin
def gen_commands():
for line in stdin:
sp = line.split()
yield (sp[0], int(sp[1]))
state_changes = {
"forward": (1,1),
"down": (0,1),
"up": (0,-1)
}
if __name__ == "__main__":
state = [0, 0]
for c, a in gen_commands():
index, multiplier = state_changes[c]
state[index] += (multiplier*a)
print( state[0]*state[1] )
#!/usr/bin/env guile
!#
(use-modules (ice-9 rdelim) (srfi srfi-1))
(define (read_sub_command_line)
(let ((line (read-line)))
(if (eof-object? line) '()
(let ((splitline (string-split line #\space)) )
(cons (car splitline)
(string->number (cadr splitline)) ) ))))
(define (read_sub_commands_recursive l next)
(if (null? next)
l
(read_sub_commands_recursive (cons next l) (read_sub_command_line) )))
(define (read_sub_commands_to_list)
(reverse (read_sub_commands_recursive '() (read_sub_command_line)) ) )
(define state_depth car)
(define state_horiz cdr)
(define (update_state command state)
(let ((motion (car command))
(arg (cdr command)) )
(cond ( (equal? motion "forward") (cons (state_depth state)
(+ (state_horiz state) arg) ))
( (equal? motion "down") (cons (+ (state_depth state) arg)
(state_horiz state)) )
( (equal? motion "up") (cons (- (state_depth state) arg)
(state_horiz state)) )
(else '(-1 . 1) ))))
(define dest (fold update_state '(0 . 0) (read_sub_commands_to_list) ))
(write-line (* (car dest) (cdr dest) ))
#!/usr/bin/env python3
from d02p1 import gen_commands
from collections import namedtuple
state_t = namedtuple("boatstate", ("depth", "horiz", "aim"))
if __name__ == "__main__":
state = state_t(depth=0, horiz=0, aim=0)
for c, x in gen_commands():
if c=="forward":
state = state_t(depth=state.depth+state.aim*x,
horiz=state.horiz+x,
aim=state.aim)
else:
state = state_t(depth=state.depth,
horiz=state.horiz,
aim=state.aim + (x* (1 if c=="down"
else -1 # up
) ))
print(state.depth*state.horiz)
#!/usr/bin/env guile
!#
(use-modules (ice-9 rdelim) (srfi srfi-1))
(define (read_sub_command_line)
(let ((line (read-line)))
(if (eof-object? line) '()
(let ((splitline (string-split line #\space)) )
(cons (car splitline)
(string->number (cadr splitline)) ) ))))
(define (read_sub_commands_recursive l next)
(if (null? next)
l
(read_sub_commands_recursive (cons next l) (read_sub_command_line) )))
(define (read_sub_commands_to_list)
(reverse (read_sub_commands_recursive '() (read_sub_command_line)) ) )
(define state_depth car)
(define state_horiz cadr)
(define state_aim caddr)
(define (update_state_aim state x direction_multiplier)
(list (state_depth state)
(state_horiz state)
(+ (state_aim state) (* x direction_multiplier)) ))
(define (update_state command state)
(let ((motion (car command))
(x (cdr command)) )
(if (equal? motion "forward")
(list (+ (state_depth state) (* (state_aim state) x) ) ; depth
(+ (state_horiz state) x) ; horiz
(state_aim state) )
(update_state_aim state x (if (equal? motion "down")
1 ; down
-1 ; otherwise up
) ))))
(define dest (fold update_state (list 0 0 0) (read_sub_commands_to_list) ))
(write-line (* (state_depth dest) (state_horiz dest) ))
#!/usr/bin/env python3
from sys import stdin
def read_diagnostic_report():
lines = [ [int(c) for c in line.strip()]
for line in stdin ]
num_lines = len(lines)
num_digits = len(lines[0])
assert(all(num_digits == len(line) for line in lines))
return lines, num_lines, num_digits
def count_column_sum(lines, i):
return sum( line[i] for line in lines )
def count_column_sums(lines, column_width):
return [
count_column_sum(lines, i)
for i in range(column_width)
]
if __name__ == "__main__":
lines, num_lines, num_digits = read_diagnostic_report()
column_sums = count_column_sums(lines, num_digits)
def create_rate_from_digit_majorities(
majority_symbol, minority_symbol):
return int(
"".join(majority_symbol if c>(num_lines-c) else minority_symbol
for c in column_sums),
2)# 2 as second argument to int() means form an int from "0" and "1"
print(create_rate_from_digit_majorities("1", "0") * # gamma rate
create_rate_from_digit_majorities("0", "1")) # epsilon rate
#!/usr/bin/env python3
from d03p1 import read_diagnostic_report, count_column_sum
def line_column_meets_criteria(line, i, line_count, column_sum, most=True):
one_count = column_sum
zero_count = line_count - one_count
return ( (most and one_count >= zero_count and line[i]==1) or
(most and zero_count > one_count and line[i]==0) or
(not most and zero_count <= one_count and line[i]==0) or
(not most and one_count < zero_count and line[i]==1) )
def filter_lines_until_criteria(lines, column_width, most=True):
for i in range(column_width):
column_sum = count_column_sum(lines, i)
lines = [
line
for line in lines
if line_column_meets_criteria(line, i, len(lines),
column_sum, most=most)
]
if len(lines)==1:
break
assert(len(lines)==1)
return int(''.join(str(c) for c in lines[0]), 2)
if __name__ == "__main__":
lines, num_lines, column_width = read_diagnostic_report()
print(filter_lines_until_criteria(lines, column_width, most=True) *
filter_lines_until_criteria(lines, column_width, most=False))
#!/usr/bin/env guile
!#
(use-modules (ice-9 rdelim) (srfi srfi-1))
(define FIVE_COLS (list 0 1 2 3 4))
(define bingocalls (map string->number (string-split (read-line) #\, )))
(read-line) ; blank line between calls and cards
(define (parse_card_line l)
(map string->number (remove (lambda (x) (equal? x ""))
(string-split l #\space) )))
(define (read_card_line)
(parse_card_line (read-line)))
(define (read_card)
(let ((first_card_line (read-line) ))
(if (eof-object? first_card_line)
'()
(let cardlineloop
((linenum 2)
(cardlines (cons (parse_card_line first_card_line) '() ))
(line (read_card_line)))
(if (= 5 linenum)
(begin
(read-line) ; blank line between cards or eof at end
(reverse (cons line cardlines)) )
(cardlineloop (+ linenum 1)
(cons line cardlines)
(read_card_line) ) )))))
(define (read_cards cards)
(let ((card (read_card)))
(if (null? card)
(reverse cards)
(read_cards (cons card cards) ))))
(define cards (read_cards '()) )
(define (isrowwinner? row calls_so_far)
(every (lambda (item) (member item calls_so_far) ) row) )
(define (anyrowwinner? card calls_so_far)
(any (lambda (row) (isrowwinner? row calls_so_far)) card))
(define (selectcol colnum full_card)
(let colloop ((rows full_card)
(selection '() ))
(if (null? rows)
selection
(colloop (cdr rows)
(cons (list-ref (car rows) colnum) selection) ))))
(define (iscolwinner? colnum card calls_so_far)
(isrowwinner? (selectcol colnum card) calls_so_far) )
(define (anycolwinner? card calls_so_far)
(any (lambda (colnum) (iscolwinner? colnum card calls_so_far) ) FIVE_COLS) )
(define (iscardwinner? card calls_so_far)
(or (anyrowwinner? card calls_so_far)
(anycolwinner? card calls_so_far)) )
(define (find_bingo_result old_calls_so_far additional_calls)
(if (null? additional_calls)
'()
(let ((call (car additional_calls)))
(let*
((calls_so_far (cons call old_calls_so_far))
(winningcard
(let cardloop ((remaining_cards cards)
(card_num 1))
(if (null? remaining_cards)
'() ; no winning card found
(if (iscardwinner? (car remaining_cards) calls_so_far)
(car remaining_cards)
(cardloop (cdr remaining_cards) (+ card_num 1)) ) ))))
(if (null? winningcard)
(find_bingo_result calls_so_far (cdr additional_calls))
(cons calls_so_far winningcard)) ))))
(define bingo_result_pair (find_bingo_result '() bingocalls) )
(define (filtersumrow row calls_so_far)
(reduce + 0 (remove (lambda (x) (member x calls_so_far)) row) ))
(define (sum_uncalled_numbers card calls_so_far)
(reduce + 0 (map (lambda (x) (filtersumrow x calls_so_far)) card)) )
(define last_number_called (caar bingo_result_pair))
(define sum_of_uncalled_numbers
(sum_uncalled_numbers (cdr bingo_result_pair)
(car bingo_result_pair)) )
(write-line (* last_number_called sum_of_uncalled_numbers))
#!/usr/bin/env guile
!#
(use-modules (ice-9 rdelim) (srfi srfi-1))
(define FIVE_COLS (list 0 1 2 3 4))
(define bingocalls (map string->number (string-split (read-line) #\, )))
(read-line) ; blank line between calls and cards
(define (parse_card_line l)
(map string->number (remove (lambda (x) (equal? x ""))
(string-split l #\space) )))
(define (read_card_line)
(parse_card_line (read-line)))
(define (read_card)
(let ((first_card_line (read-line) ))
(if (eof-object? first_card_line)
'()
(let cardlineloop
((linenum 2)
(cardlines (cons (parse_card_line first_card_line) '() ))
(line (read_card_line)))
(if (= 5 linenum)
(begin
(read-line) ; blank line between cards or eof at end
(reverse (cons line cardlines)) )
(cardlineloop (+ linenum 1)
(cons line cardlines)
(read_card_line) ) )))))
(define (read_cards cards)
(let ((card (read_card)))
(if (null? card)
(reverse cards)
(read_cards (cons card cards) ))))
(define cards (read_cards '()) )
(define (isrowwinner? row calls_so_far)
(every (lambda (item) (member item calls_so_far) ) row) )
(define (anyrowwinner? card calls_so_far)
(any (lambda (row) (isrowwinner? row calls_so_far)) card))
(define (selectcol colnum full_card)
(let colloop ((rows full_card)
(selection '() ))
(if (null? rows)
selection
(colloop (cdr rows)
(cons (list-ref (car rows) colnum) selection) ))))
(define (iscolwinner? colnum card calls_so_far)
(isrowwinner? (selectcol colnum card) calls_so_far) )
(define (anycolwinner? card calls_so_far)
(any (lambda (colnum) (iscolwinner? colnum card calls_so_far) ) FIVE_COLS) )
(define (iscardwinner? card calls_so_far)
(or (anyrowwinner? card calls_so_far)
(anycolwinner? card calls_so_far)) )
(define (find_last_card old_calls_so_far additional_calls activecards)
(if (null? additional_calls)
'()
(let ((call (car additional_calls)))
(let*
((calls_so_far (cons call old_calls_so_far))
(lossingcards
(remove (lambda (x) (iscardwinner? x calls_so_far))
activecards) ) )
(if (= 1 (length lossingcards))
(car lossingcards)
(if (= 0 (length lossingcards))
(error "ran out of cards")
(find_last_card calls_so_far (cdr additional_calls)
lossingcards) ))))))
(define last_card (find_last_card '() bingocalls cards))
(define cards (list last_card))
(define (find_bingo_result old_calls_so_far additional_calls)
(if (null? additional_calls)
'()
(let ((call (car additional_calls)))
(let*
((calls_so_far (cons call old_calls_so_far))
(winningcard
(let cardloop ((remaining_cards cards)
(card_num 1))
(if (null? remaining_cards)
'() ; no winning card found
(if (iscardwinner? (car remaining_cards) calls_so_far)
(car remaining_cards)
(cardloop (cdr remaining_cards) (+ card_num 1)) ) ))))
(if (null? winningcard)
(find_bingo_result calls_so_far (cdr additional_calls))
(cons calls_so_far winningcard)) ))))
(define bingo_result_pair (find_bingo_result '() bingocalls) )
(define (filtersumrow row calls_so_far)
(reduce + 0 (remove (lambda (x) (member x calls_so_far)) row) ))
(define (sum_uncalled_numbers card calls_so_far)
(reduce + 0 (map (lambda (x) (filtersumrow x calls_so_far)) card)) )
(define last_number_called (caar bingo_result_pair))
(define sum_of_uncalled_numbers
(sum_uncalled_numbers (cdr bingo_result_pair)
(car bingo_result_pair)) )
(write-line (* last_number_called sum_of_uncalled_numbers))
#!/usr/bin/python3
# https://adventofcode.com/2021/day/5 part1
# pair programming by Sara Arenson and Mark Jenkins
# works with python2.7 or 3
from __future__ import print_function
import sys
if sys.version_info[0] == 2:
range = xrange
from sys import stdin
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
def horizontal(pt1, pt2):
return pt1.y == pt2.y
def vertical(pt1, pt2):
return pt1.x == pt2.x
def horiz_or_vert(pt1, pt2):
return horizontal(pt1, pt2) or vertical(pt1, pt2)
def generate_line_pts(pt1, pt2):
line_pts = [pt1, pt2]
line_pts.sort()
new_pt1 = line_pts[0]
new_pt2 = line_pts[1]
if horizontal(*line_pts):
for i in range(new_pt1.x, new_pt2.x+1):
yield Point(i, new_pt1.y)
if vertical(*line_pts):
for i in range(new_pt1.y, new_pt2.y+1):
yield Point(new_pt1.x, i)
def generate_horiz_or_verts(pt1, pt2):
return ( () if not horiz_or_vert(pt1, pt2)
else generate_line_pts(pt1, pt2) )
def problem_input():
return (
(Point(*[ int(item) for item in p.split(",") ])
for p in line.strip().split(" ")[0::2])
for line in stdin )
if __name__ == "__main__":
one_point = set()
two_or_more = set()
for pt1, pt2 in problem_input():
for pt in generate_horiz_or_verts(pt1, pt2):
if pt in one_point:
two_or_more.add(pt)
else:
one_point.add(pt)
print(len(two_or_more))
from collections import namedtuple
from aoc2021_d05p1 import Point, problem_input, generate_horiz_or_verts
def is_45_diagonal(pt1, pt2):
return abs(pt1.x - pt2.x) == abs(pt1.y - pt2.y)
def gen_45_diag(pt1, pt2):
assert( is_45_diagonal(pt1, pt2) )
line_pts = [pt1, pt2]
line_pts.sort()
new_pt1 = line_pts[0]
new_pt2 = line_pts[1]
y_direction = (1 if new_pt1.y < new_pt2.y else -1)
for x,y in zip( range(new_pt1.x, new_pt2.x+1),
range(new_pt1.y, new_pt2.y+y_direction, y_direction) ):
yield Point(x,y)
if __name__ == "__main__":
one_point = set()
two_or_more = set()
for pt1, pt2 in problem_input():
if is_45_diagonal(pt1, pt2):
for pt in gen_45_diag(pt1, pt2):
if pt in one_point:
two_or_more.add(pt)
else:
one_point.add(pt)
else:
for pt in generate_horiz_or_verts(pt1, pt2):
if pt in one_point:
two_or_more.add(pt)
else:
one_point.add(pt)
print(len(two_or_more))
(use-modules (ice-9 rdelim) (srfi srfi-1) )
(define (split_at_to_pair l n)
(define-values (x y) (split-at l n))
(cons x y) )
;;; 10 zeros
(define empty_lantern_counts (map (lambda (x) 0) (iota 10)) )
(define problem_input
(map string->number (string-split (read-line) #\,) ) )
(define (increment_count_at_target_by_n counts target n)
(let* ((split_counts (split_at_to_pair counts target))
(first_half (car split_counts))
(second_half (cdr split_counts)) )
(append first_half
(list (+ (car second_half) n))
(cdr second_half)) ))
(define (increment_counts counts all_targets)
(fold (lambda (target new_counts)
(increment_count_at_target_by_n new_counts target 1))
counts
all_targets))
(define input_lantern_counts
(increment_counts empty_lantern_counts problem_input) )
(define (update_lantern_cycle counts)
(let ((zero_count (car counts))
(shifted_counts (cdr counts)) )
(increment_count_at_target_by_n
(increment_count_at_target_by_n
(append shifted_counts '(0) )
6
zero_count)
8
zero_count )))
(define (total_after_n_rounds n)
(reduce + "error"
(do ((i 0 (+ i 1))
(counts input_lantern_counts (update_lantern_cycle counts)) )
((= i n) counts) )))
(write-line (total_after_n_rounds 80))
(write-line (total_after_n_rounds 256))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment