-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
340 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import "stdlib/io.jou" | ||
import "stdlib/str.jou" | ||
|
||
class Hand: | ||
letters: byte[6] | ||
bid: int | ||
|
||
def count(self, letter: byte) -> int: | ||
n = 0 | ||
for i = 0; i < 5; i++: | ||
if self->letters[i] == letter: | ||
n++ | ||
return n | ||
|
||
def all_same(self) -> bool: | ||
return self->count(self->letters[0]) == 5 | ||
|
||
def all_but_one_same(self) -> bool: | ||
return self->count(self->letters[0]) == 4 or self->count(self->letters[1]) == 4 | ||
|
||
def three_same_and_two_same(self) -> bool: | ||
# ensure that every count is either 3 or 2 | ||
for i = 0; i < 5; i++: | ||
n = self->count(self->letters[i]) | ||
if n != 3 and n != 2: | ||
return False | ||
return True | ||
|
||
def three_same_two_distinct(self) -> bool: | ||
# ensure that every count is either 3 or 1, and count 3 appears | ||
found3 = False | ||
for i = 0; i < 5; i++: | ||
n = self->count(self->letters[i]) | ||
if n != 3 and n != 1: | ||
return False | ||
if n == 3: | ||
found3 = True | ||
return found3 | ||
|
||
def two_pairs_one_distinct(self) -> bool: | ||
# ensure that every count is either 2 or 1, and count 1 appears only once | ||
count1 = 0 | ||
for i = 0; i < 5; i++: | ||
n = self->count(self->letters[i]) | ||
if n != 2 and n != 1: | ||
return False | ||
if n == 1: | ||
count1++ | ||
return count1 == 1 | ||
|
||
def one_pair(self) -> bool: | ||
# ensure that every count is either 2 or 1, and exactly 2 cards have count 2 | ||
count2 = 0 | ||
for i = 0; i < 5; i++: | ||
n = self->count(self->letters[i]) | ||
if n != 2 and n != 1: | ||
return False | ||
if n == 2: | ||
count2++ | ||
return count2 == 2 | ||
|
||
def all_distinct(self) -> bool: | ||
for i = 0; i < 5; i++: | ||
if self->count(self->letters[i]) != 1: | ||
return False | ||
return True | ||
|
||
def hand_type_strength(self) -> int: | ||
# check that i did this right, exactly one should be true | ||
# return index of true in list | ||
bools = [ | ||
self->all_distinct(), | ||
self->one_pair(), | ||
self->two_pairs_one_distinct(), | ||
self->three_same_two_distinct(), | ||
self->three_same_and_two_same(), | ||
self->all_but_one_same(), | ||
self->all_same(), | ||
] | ||
|
||
result = -1 | ||
for i = 0; i < sizeof(bools)/sizeof(bools[0]); i++: | ||
if bools[i]: | ||
assert result == -1 | ||
result = i | ||
|
||
assert result != -1 | ||
return result | ||
|
||
# Return value: | ||
# +1 if self > other | ||
# 0 if self == other | ||
# -1 if self < other | ||
def compare(self, other: Hand*) -> int: | ||
if self->hand_type_strength() > other->hand_type_strength(): | ||
return 1 | ||
if self->hand_type_strength() < other->hand_type_strength(): | ||
return -1 | ||
|
||
for i = 0; i < 5; i++: | ||
s = "23456789TJQKA" | ||
self_idx_ptr = strchr(s, self->letters[i]) | ||
other_idx_ptr = strchr(s, other->letters[i]) | ||
assert self_idx_ptr != NULL and other_idx_ptr != NULL | ||
if self_idx_ptr > other_idx_ptr: | ||
return 1 | ||
if self_idx_ptr < other_idx_ptr: | ||
return -1 | ||
|
||
return 0 | ||
|
||
|
||
def swap(h1: Hand*, h2: Hand*) -> void: | ||
temp = *h1 | ||
*h1 = *h2 | ||
*h2 = temp | ||
|
||
|
||
def sort(hands: Hand*, nhands: int) -> void: | ||
# bubble sort go brrr | ||
for sorted_part_len = 1; sorted_part_len < nhands; sorted_part_len++: | ||
i = sorted_part_len | ||
while i > 0 and hands[i-1].compare(&hands[i]) == 1: | ||
swap(&hands[i-1], &hands[i]) | ||
i-- | ||
|
||
|
||
def main() -> int: | ||
hands: Hand[2000] | ||
nhands = 0 | ||
|
||
f = fopen("sampleinput.txt", "r") | ||
assert f != NULL | ||
|
||
while fscanf(f, "%5s %d\n", &hands[nhands].letters, &hands[nhands].bid) == 2: | ||
nhands++ | ||
assert nhands < sizeof(hands)/sizeof(hands[0]) | ||
|
||
fclose(f) | ||
|
||
sort(hands, nhands) | ||
|
||
sum = 0 | ||
for i = 0; i < nhands; i++: | ||
sum += (i+1) * hands[i].bid | ||
printf("%d\n", sum) # Output: 6440 | ||
|
||
return 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
import "stdlib/io.jou" | ||
import "stdlib/str.jou" | ||
import "stdlib/mem.jou" | ||
|
||
class Hand: | ||
letters: byte[6] | ||
bid: int | ||
|
||
# optimization to speed up sorting | ||
cached_hand_type_strength: int | ||
|
||
def count(self, letter: byte) -> int: | ||
n = 0 | ||
for i = 0; i < 5; i++: | ||
if self->letters[i] == letter: | ||
n++ | ||
return n | ||
|
||
def all_same(self) -> bool: | ||
return self->count(self->letters[0]) == 5 | ||
|
||
def all_but_one_same(self) -> bool: | ||
return self->count(self->letters[0]) == 4 or self->count(self->letters[1]) == 4 | ||
|
||
def three_same_and_two_same(self) -> bool: | ||
# ensure that every count is either 3 or 2 | ||
for i = 0; i < 5; i++: | ||
n = self->count(self->letters[i]) | ||
if n != 3 and n != 2: | ||
return False | ||
return True | ||
|
||
def three_same_two_distinct(self) -> bool: | ||
# ensure that every count is either 3 or 1, and count 3 appears | ||
found3 = False | ||
for i = 0; i < 5; i++: | ||
n = self->count(self->letters[i]) | ||
if n != 3 and n != 1: | ||
return False | ||
if n == 3: | ||
found3 = True | ||
return found3 | ||
|
||
def two_pairs_one_distinct(self) -> bool: | ||
# ensure that every count is either 2 or 1, and count 1 appears only once | ||
count1 = 0 | ||
for i = 0; i < 5; i++: | ||
n = self->count(self->letters[i]) | ||
if n != 2 and n != 1: | ||
return False | ||
if n == 1: | ||
count1++ | ||
return count1 == 1 | ||
|
||
def one_pair(self) -> bool: | ||
# ensure that every count is either 2 or 1, and exactly 2 cards have count 2 | ||
count2 = 0 | ||
for i = 0; i < 5; i++: | ||
n = self->count(self->letters[i]) | ||
if n != 2 and n != 1: | ||
return False | ||
if n == 2: | ||
count2++ | ||
return count2 == 2 | ||
|
||
def all_distinct(self) -> bool: | ||
for i = 0; i < 5; i++: | ||
if self->count(self->letters[i]) != 1: | ||
return False | ||
return True | ||
|
||
def hand_type_strength_without_J_special_casing(self) -> int: | ||
# check that i did this right, exactly one should be true | ||
# return index of true in list | ||
bools = [ | ||
self->all_distinct(), | ||
self->one_pair(), | ||
self->two_pairs_one_distinct(), | ||
self->three_same_two_distinct(), | ||
self->three_same_and_two_same(), | ||
self->all_but_one_same(), | ||
self->all_same(), | ||
] | ||
|
||
result = -1 | ||
for i = 0; i < sizeof(bools)/sizeof(bools[0]); i++: | ||
if bools[i]: | ||
assert result == -1 | ||
result = i | ||
|
||
assert result != -1 | ||
return result | ||
|
||
def hand_type_strength(self) -> int: | ||
if self->cached_hand_type_strength != -1: | ||
return self->cached_hand_type_strength | ||
|
||
variations: Hand* = malloc(sizeof(variations[0])) | ||
variations[0] = *self | ||
nvariations = 1 | ||
|
||
for i = 0; i < 5; i++: | ||
if self->letters[i] == 'J': | ||
# Duplicate each existing variation 13 times | ||
nvariations *= 13 | ||
variations = realloc(variations, sizeof(variations)[0] * nvariations) | ||
for isrc = nvariations/13 - 1; isrc >= 0; isrc--: | ||
for idest = 13*isrc; idest < 13*(isrc+1); idest++: | ||
variations[idest] = variations[isrc] | ||
|
||
# Replace i'th letter in every possible way | ||
for k = 0; k < nvariations; k++: | ||
variations[k].letters[i] = "J23456789TQKA"[k % 13] | ||
|
||
best = -1 | ||
for i = 0; i < nvariations; i++: | ||
value = variations[i].hand_type_strength_without_J_special_casing() | ||
if value > best: | ||
best = value | ||
|
||
free(variations) | ||
self->cached_hand_type_strength = best | ||
return best | ||
|
||
# Return value: | ||
# +1 if self > other | ||
# 0 if self == other | ||
# -1 if self < other | ||
def compare(self, other: Hand*) -> int: | ||
if self->hand_type_strength() > other->hand_type_strength(): | ||
return 1 | ||
if self->hand_type_strength() < other->hand_type_strength(): | ||
return -1 | ||
|
||
for i = 0; i < 5; i++: | ||
s = "J23456789TQKA" | ||
self_idx_ptr = strchr(s, self->letters[i]) | ||
other_idx_ptr = strchr(s, other->letters[i]) | ||
assert self_idx_ptr != NULL and other_idx_ptr != NULL | ||
if self_idx_ptr > other_idx_ptr: | ||
return 1 | ||
if self_idx_ptr < other_idx_ptr: | ||
return -1 | ||
|
||
return 0 | ||
|
||
|
||
def swap(h1: Hand*, h2: Hand*) -> void: | ||
temp = *h1 | ||
*h1 = *h2 | ||
*h2 = temp | ||
|
||
|
||
def sort(hands: Hand*, nhands: int) -> void: | ||
# bubble sort go brrr | ||
for sorted_part_len = 1; sorted_part_len < nhands; sorted_part_len++: | ||
i = sorted_part_len | ||
while i > 0 and hands[i-1].compare(&hands[i]) == 1: | ||
swap(&hands[i-1], &hands[i]) | ||
i-- | ||
|
||
|
||
def main() -> int: | ||
hands: Hand[2000] | ||
nhands = 0 | ||
|
||
f = fopen("sampleinput.txt", "r") | ||
assert f != NULL | ||
|
||
while fscanf(f, "%5s %d\n", &hands[nhands].letters, &hands[nhands].bid) == 2: | ||
hands[nhands].cached_hand_type_strength = -1 | ||
nhands++ | ||
assert nhands < sizeof(hands)/sizeof(hands[0]) | ||
|
||
fclose(f) | ||
|
||
sort(hands, nhands) | ||
|
||
sum = 0 | ||
for i = 0; i < nhands; i++: | ||
sum += (i+1) * hands[i].bid | ||
printf("%d\n", sum) # Output: 5905 | ||
|
||
return 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
32T3K 765 | ||
T55J5 684 | ||
KK677 28 | ||
KTJJT 220 | ||
QQQJA 483 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters