aoc2024/days/day23.st
2024-12-23 08:37:42 +00:00

95 lines
2.8 KiB
Smalltalk

String extend [
toPuterId
[ ^(self inject: 0 into: [:a :c | a * 26 + c asciiValue - 97]) + 1 ]
]
String class extend [
fromPuterId: x
[ | d2 d1 t |
t := x - 1.
d1 := t // 26.
d2 := t \\ 26.
^String with: (Character asciiValue: d1 + 97)
with: (Character asciiValue: d2 + 97) ]
]
Object subclass: Puter [
| id allEdges forwardEdges |
forwardEdges [^forwardEdges]
id: i [id := i]
initialize [allEdges := Set new. forwardEdges := Set new]
addEdge: o
[ allEdges add: o.
id < o ifTrue: [forwardEdges add: o]. ]
]
Puter class extend [
isChiefHistorians: id [ ^(id - 1 // 26) = 19 "= $t" ]
]
Object subclass: Network [
| puters biggestParty currentParty |
puters [^puters]
initialize
[ puters := 1 to: 26 * 26 collect: [:id | Puter new id: id] ]
edges: edges
[ edges do: [
:e | (e tokenize: '-') letArrayInBlock: [
:lhs :rhs | | li ri |
li := lhs toPuterId. ri := rhs toPuterId.
(puters at: li) addEdge: ri.
(puters at: ri) addEdge: li.
]]]
findTriangles
[ | coll | coll := OrderedCollection new.
puters keysAndValuesDo: [
:c1 :p1 |
p1 forwardEdges do: [
:c2 | | p2 | p2 := puters at: c2.
p1 forwardEdges & p2 forwardEdges do: [
:c3 | coll add: {c1. c2. c3}]]].
^coll ]
findBiggestParty
[ currentParty := OrderedCollection new.
biggestParty := {}.
puters keysAndValuesDo: [
:c1 :p1 |
currentParty add: c1.
[ self biggestPartyFromSet: p1 forwardEdges
] ensure: [ currentParty removeLast ]].
^biggestParty ]
biggestPartyFromSet: set
[ set do: [
:cn | | pn | pn := puters at: cn.
currentParty add: cn.
[ currentParty size > biggestParty size ifTrue: [
biggestParty := currentParty asArray ].
self biggestPartyFromSet: set & pn forwardEdges
] ensure: [ currentParty removeLast ]]]
visualize
[ AOC visualizeWithExt: '.dot' do: [
:io |
io << 'graph{'.
puters keysAndValuesDo: [
:c1 :p1 | | n1 | n1 := String fromPuterId: c1.
p1 forwardEdges do: [
:c2 | | n2 | n2 := String fromPuterId: c2.
io << n1 << '--' << n2 << ';'.]].
io << '}'; nl ]]
]
AOC input: [ Network new edges: stdin lines ];
part1: [ :net | net chain findTriangles;
select: [:it | it anySatisfy: [
:c | Puter isChiefHistorians: c]];
size ];
part2: [ :net | net chain findBiggestParty;
collect: [:it | String fromPuterId: it];
join: ',' ];
result: [ :net :part | part value: net ];
finish.