Day 25
This commit is contained in:
parent
b3ebcbd041
commit
eb829e8986
3 changed files with 110 additions and 73 deletions
|
|
@ -114,79 +114,6 @@ Object subclass: Racetrack [
|
||||||
block value: dpos value: ddist ] asSpreader ]
|
block value: dpos value: ddist ] asSpreader ]
|
||||||
]
|
]
|
||||||
|
|
||||||
Object subclass: KDTree [
|
|
||||||
from: min to: max do: block
|
|
||||||
[ self subclassResponsibility ]
|
|
||||||
]
|
|
||||||
KDTree class extend [
|
|
||||||
fromPoints: points
|
|
||||||
[ ^self fromShuffledPoints: (Random new shuffle: points asArray) ]
|
|
||||||
|
|
||||||
fromShuffledPoints: points
|
|
||||||
[ ^self fromShuffledPoints: points axis: 1 ]
|
|
||||||
|
|
||||||
leafMaxSize [ ^5 ]
|
|
||||||
fromShuffledPoints: points axis: ax
|
|
||||||
[ | med splits dims nextAx value |
|
|
||||||
points size <= self leafMaxSize ifTrue: [^KDLeaf new points: points asArray].
|
|
||||||
med := self guessMedian: points axis: ax.
|
|
||||||
dims := med size.
|
|
||||||
nextAx := ax \\ dims + 1.
|
|
||||||
value := med at: ax.
|
|
||||||
splits := self splitPoints: points axis: ax on: value.
|
|
||||||
^KDInner new
|
|
||||||
left: (self fromShuffledPoints: (splits at: 1) axis: nextAx)
|
|
||||||
right: (self fromShuffledPoints: (splits at: 2) axis: nextAx)
|
|
||||||
axis: ax
|
|
||||||
value: value ]
|
|
||||||
|
|
||||||
splitPoints: points axis: ax on: val
|
|
||||||
[ | l r fairLeft |
|
|
||||||
l := OrderedCollection new.
|
|
||||||
r := OrderedCollection new.
|
|
||||||
fairLeft := true.
|
|
||||||
points do: [
|
|
||||||
:point | | v onLeft |
|
|
||||||
v := point at: ax.
|
|
||||||
onLeft := (v < val) or: [
|
|
||||||
v = val and: [fairLeft := fairLeft not. fairLeft]].
|
|
||||||
(onLeft ifTrue: [l] ifFalse: [r]) add: point ].
|
|
||||||
^{l . r} ]
|
|
||||||
|
|
||||||
medianGuessSize [ ^5 ]
|
|
||||||
guessMedian: points axis: ax
|
|
||||||
[ | arr |
|
|
||||||
arr := 1 to: (points size min: self medianGuessSize)
|
|
||||||
collect: [:i | points at: i].
|
|
||||||
arr sort: [:l :r | (l at: ax) <= (r at: ax)].
|
|
||||||
^arr at: arr size // 2 + 1 ]
|
|
||||||
]
|
|
||||||
|
|
||||||
KDTree subclass: KDLeaf [
|
|
||||||
| points |
|
|
||||||
points: n [points := n. "self class leafSize: points size"]
|
|
||||||
from: min to: max do: block [ points do: block ]
|
|
||||||
|
|
||||||
printOn: st [ st << 'lf' << points ]
|
|
||||||
]
|
|
||||||
KDLeaf class extend [
|
|
||||||
| leafSizes |
|
|
||||||
leafSizes [ ^leafSizes ifNil: [leafSizes := Bag new] ]
|
|
||||||
leafSize: sz [ self leafSizes add: sz ]
|
|
||||||
]
|
|
||||||
|
|
||||||
KDTree subclass: KDInner [
|
|
||||||
| left right axis value |
|
|
||||||
left: l right: r axis: ax value: v
|
|
||||||
[left:=l. right:=r. axis:=ax. value:=v]
|
|
||||||
from: min to: max do: block
|
|
||||||
[ (min at: axis) <= value ifTrue: [ left from: min to: max do: block ].
|
|
||||||
(max at: axis) >= value ifTrue: [ right from: min to: max do: block ] ]
|
|
||||||
|
|
||||||
printOn: st [ st << '{' << left << ' <= [' << axis << '] '
|
|
||||||
<< value << ' <= ' << right << '}' ]
|
|
||||||
]
|
|
||||||
|
|
||||||
AOC input: [ Racetrack new rows: stdin toLines asArray ];
|
AOC input: [ Racetrack new rows: stdin toLines asArray ];
|
||||||
part1: 2; part2: 20;
|
part1: 2; part2: 20;
|
||||||
result: [ :track :time | track countCheatsWithTime: time ];
|
result: [ :track :time | track countCheatsWithTime: time ];
|
||||||
|
|
|
||||||
36
days/day25.st
Normal file
36
days/day25.st
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
Object subclass: KeyOrLock [
|
||||||
|
| isLock height value |
|
||||||
|
value [^value]
|
||||||
|
isLock [^isLock]
|
||||||
|
|
||||||
|
rows: r
|
||||||
|
[ | cols |
|
||||||
|
cols := r lines transposed.
|
||||||
|
isLock := cols allSatisfy: [:it | (it at: 1) = $#].
|
||||||
|
height := (cols at: 1) size.
|
||||||
|
value := cols collect: [
|
||||||
|
:it | | first | first := it at: 1.
|
||||||
|
it count: [:c | c = first]] ]
|
||||||
|
]
|
||||||
|
|
||||||
|
AOC input: [ stdin contents splitDoubleNl collect:
|
||||||
|
[:it | KeyOrLock new rows: it] ];
|
||||||
|
part1: [ :input | | locks keys minPos total |
|
||||||
|
locks := OrderedCollection new.
|
||||||
|
keys := OrderedCollection new.
|
||||||
|
input do: [:it | it isLock
|
||||||
|
ifTrue: [locks add: it value]
|
||||||
|
ifFalse: [keys add: it value]].
|
||||||
|
locks := KDTree fromPoints: locks.
|
||||||
|
|
||||||
|
total := 0.
|
||||||
|
minPos := Array new: (keys at: 1) size withAll: 0.
|
||||||
|
keys do: [
|
||||||
|
:key | locks from: minPos to: key do: [
|
||||||
|
:lock |
|
||||||
|
((key with: lock) allSatisfy: [
|
||||||
|
:k :l | k >= l ] asSpreader)
|
||||||
|
ifTrue: [total := total + 1]]].
|
||||||
|
total ];
|
||||||
|
result: [ :input :part | part value: input ];
|
||||||
|
finish.
|
||||||
|
|
@ -419,3 +419,77 @@ Random extend [
|
||||||
].
|
].
|
||||||
^coll ]
|
^coll ]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
"--- KDTree ---"
|
||||||
|
Object subclass: KDTree [
|
||||||
|
from: min to: max do: block
|
||||||
|
[ self subclassResponsibility ]
|
||||||
|
]
|
||||||
|
KDTree class extend [
|
||||||
|
fromPoints: points
|
||||||
|
[ ^self fromShuffledPoints: (Random new shuffle: points asArray) ]
|
||||||
|
|
||||||
|
fromShuffledPoints: points
|
||||||
|
[ ^self fromShuffledPoints: points axis: 1 ]
|
||||||
|
|
||||||
|
leafMaxSize [ ^5 ]
|
||||||
|
fromShuffledPoints: points axis: ax
|
||||||
|
[ | med splits dims nextAx value |
|
||||||
|
points size <= self leafMaxSize ifTrue: [^KDLeaf new points: points asArray].
|
||||||
|
med := self guessMedian: points axis: ax.
|
||||||
|
dims := med size.
|
||||||
|
nextAx := ax \\ dims + 1.
|
||||||
|
value := med at: ax.
|
||||||
|
splits := self splitPoints: points axis: ax on: value.
|
||||||
|
^KDInner new
|
||||||
|
left: (self fromShuffledPoints: (splits at: 1) axis: nextAx)
|
||||||
|
right: (self fromShuffledPoints: (splits at: 2) axis: nextAx)
|
||||||
|
axis: ax
|
||||||
|
value: value ]
|
||||||
|
|
||||||
|
splitPoints: points axis: ax on: val
|
||||||
|
[ | l r fairLeft |
|
||||||
|
l := OrderedCollection new.
|
||||||
|
r := OrderedCollection new.
|
||||||
|
fairLeft := true.
|
||||||
|
points do: [
|
||||||
|
:point | | v onLeft |
|
||||||
|
v := point at: ax.
|
||||||
|
onLeft := (v < val) or: [
|
||||||
|
v = val and: [fairLeft := fairLeft not. fairLeft]].
|
||||||
|
(onLeft ifTrue: [l] ifFalse: [r]) add: point ].
|
||||||
|
^{l . r} ]
|
||||||
|
|
||||||
|
medianGuessSize [ ^5 ]
|
||||||
|
guessMedian: points axis: ax
|
||||||
|
[ | arr |
|
||||||
|
arr := 1 to: (points size min: self medianGuessSize)
|
||||||
|
collect: [:i | points at: i].
|
||||||
|
arr sort: [:l :r | (l at: ax) <= (r at: ax)].
|
||||||
|
^arr at: arr size // 2 + 1 ]
|
||||||
|
]
|
||||||
|
|
||||||
|
KDTree subclass: KDLeaf [
|
||||||
|
| points |
|
||||||
|
points: n [points := n. "self class leafSize: points size"]
|
||||||
|
from: min to: max do: block [ points do: block ]
|
||||||
|
|
||||||
|
printOn: st [ st << 'lf' << points ]
|
||||||
|
]
|
||||||
|
KDLeaf class extend [
|
||||||
|
| leafSizes |
|
||||||
|
leafSizes [ ^leafSizes ifNil: [leafSizes := Bag new] ]
|
||||||
|
leafSize: sz [ self leafSizes add: sz ]
|
||||||
|
]
|
||||||
|
|
||||||
|
KDTree subclass: KDInner [
|
||||||
|
| left right axis value |
|
||||||
|
left: l right: r axis: ax value: v
|
||||||
|
[left:=l. right:=r. axis:=ax. value:=v]
|
||||||
|
from: min to: max do: block
|
||||||
|
[ (min at: axis) <= value ifTrue: [ left from: min to: max do: block ].
|
||||||
|
(max at: axis) >= value ifTrue: [ right from: min to: max do: block ] ]
|
||||||
|
|
||||||
|
printOn: st [ st << '{' << left << ' <= [' << axis << '] '
|
||||||
|
<< value << ' <= ' << right << '}' ]
|
||||||
|
]
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue