bottom side of a pcb
kartoffelsaft
Surprised TOEM isn't on your list, given the premise is pretty much exactly what you describe. Last I checked it comes up on the first page or something if you sort steam by highest rated.
Lunacid might also be a good game. I think it fits your criteria for me, but that might just be for me.
I dunno, having two primes sum to a power of two is undeniably powerful in my experience. The number of times a calculation goes from tedious to trivial from this sum is incalculable. The lowest I'd put it is A.
Darn that sucks to hear. I was somewhat active several months ago. Unfortunately the server never hit "critical mass". My interest in any given game also waxes & wanes significantly so I know I kinda abruptly stopped playing.
~~Isn't the Weierstrass function a counterexample to the premise?~~ Wait no, I misread. It's the converse.
I have mine set up with a bunch of categories that are sorted with a prepended 3-digit number. Allows me to have different sections of category without it getting mixed up. ex:
010 S
011 A+
012 A
013 A-
014 B+
etc...
350 plz play soon
355 wont play
...
800 dont remember buying this
Odin
When I read the problem description I expected the input to also be 2 digit numbers. When I looked at it I just had to say "huh."
Second part I think you definitely have to do in reverse (edit: if you are doing a linear search for the answer), as that allows you to nope out as soon as you find a match, whereas with doing it forward you have to keep checking just in case.
package day5
import "core:fmt"
import "core:strings"
import "core:slice"
import "core:strconv"
Range :: struct {
dest: int,
src: int,
range: int,
}
Mapper :: struct {
ranges: []Range,
}
parse_range :: proc(s: string) -> (ret: Range) {
rest := s
parseLen := -1
destOk: bool
ret.dest, destOk = strconv.parse_int(rest, 10, &parseLen)
rest = strings.trim_left_space(rest[parseLen:])
srcOk: bool
ret.src, srcOk = strconv.parse_int(rest, 10, &parseLen)
rest = strings.trim_left_space(rest[parseLen:])
rangeOk: bool
ret.range, rangeOk = strconv.parse_int(rest, 10, &parseLen)
return
}
parse_mapper :: proc(ss: []string) -> (ret: Mapper) {
ret.ranges = make([]Range, len(ss)-1)
for s, i in ss[1:] {
ret.ranges[i] = parse_range(s)
}
return
}
parse_mappers :: proc(ss: []string) -> []Mapper {
mapsStr := make([dynamic][]string)
defer delete(mapsStr)
restOfLines := ss
isLineEmpty :: proc(s: string)->bool {return len(s)==0}
for i, found := slice.linear_search_proc(restOfLines, isLineEmpty);
found;
i, found = slice.linear_search_proc(restOfLines, isLineEmpty) {
append(&mapsStr, restOfLines[:i])
restOfLines = restOfLines[i+1:]
}
append(&mapsStr, restOfLines[:])
return slice.mapper(mapsStr[1:], parse_mapper)
}
apply_mapper :: proc(mapper: Mapper, num: int) -> int {
for r in mapper.ranges {
if num >= r.src && num - r.src < r.range do return num - r.src + r.dest
}
return num
}
p1 :: proc(input: []string) {
maps := parse_mappers(input)
defer {
for m in maps do delete(m.ranges)
delete(maps)
}
restSeeds := input[0][len("seeds: "):]
min := 0x7fffffff
for len(restSeeds) > 0 {
seedLen := -1
seed, seedOk := strconv.parse_int(restSeeds, 10, &seedLen)
restSeeds = strings.trim_left_space(restSeeds[seedLen:])
fmt.print(seed)
for m in maps {
seed = apply_mapper(m, seed)
fmt.print(" ->", seed)
}
fmt.println()
if seed < min do min = seed
}
fmt.println(min)
}
apply_mapper_reverse :: proc(mapper: Mapper, num: int) -> int {
for r in mapper.ranges {
if num >= r.dest && num - r.dest < r.range do return num - r.dest + r.src
}
return num
}
p2 :: proc(input: []string) {
SeedRange :: struct {
start: int,
len: int,
}
seeds := make([dynamic]SeedRange)
restSeeds := input[0][len("seeds: "):]
for len(restSeeds) > 0 {
seedLen := -1
seedS, seedSOk := strconv.parse_int(restSeeds, 10, &seedLen)
restSeeds = strings.trim_left_space(restSeeds[seedLen:])
seedL, seedLOk := strconv.parse_int(restSeeds, 10, &seedLen)
restSeeds = strings.trim_left_space(restSeeds[seedLen:])
append(&seeds, SeedRange{seedS, seedL})
}
maps := parse_mappers(input)
defer {
for m in maps do delete(m.ranges)
delete(maps)
}
for i := 0; true; i += 1 {
rseed := i
#reverse for m in maps {
rseed = apply_mapper_reverse(m, rseed)
}
found := false
for sr in seeds {
if rseed >= sr.start && rseed < sr.start + sr.len {
found = true
break
}
}
if found {
fmt.println(i)
break
}
}
}
Oh yeah, I misspoke, gonna edit.
hmm, my code keeps getting truncated at for y in ..
, anyone have any idea why? Maybe the "<" right after that confuses a parser somewhere?
Did this in Odin
Here's a tip: if you are using a language / standard library that doesn't have a set, you can mimic it with a map from your key to a nullary (in this case an empty struct)
package day3
import "core:fmt"
import "core:strings"
import "core:unicode"
import "core:strconv"
flood_get_num :: proc(s: string, i: int) -> (parsed: int, pos: int) {
if !unicode.is_digit(rune(s[i])) do return -99999, -1
pos = strings.last_index_proc(s[:i+1], proc(r:rune)->bool{return !unicode.is_digit(r)})
pos += 1
ok: bool
parsed, ok = strconv.parse_int(s[pos:])
return parsed, pos
}
p1 :: proc(input: []string) {
// wow what a gnarly type
foundNumSet := make(map[[2]int]struct{})
defer delete(foundNumSet)
total := 0
for y in 0..
Did mine in Odin. Found this day's to be super easy, most of the challenge was just parsing.
package day2
import "core:fmt"
import "core:strings"
import "core:strconv"
import "core:unicode"
Round :: struct {
red: int,
green: int,
blue: int,
}
parse_round :: proc(s: string) -> Round {
ret: Round
rest := s
for {
nextNumAt := strings.index_proc(rest, unicode.is_digit)
if nextNumAt == -1 do break
rest = rest[nextNumAt:]
numlen: int
num, ok := strconv.parse_int(rest, 10, &numlen)
rest = rest[numlen+len(" "):]
if rest[:3] == "red" {
ret.red = num
} else if rest[:4] == "blue" {
ret.blue = num
} else if rest[:5] == "green" {
ret.green = num
}
}
return ret
}
Game :: struct {
id: int,
rounds: [dynamic]Round,
}
parse_game :: proc(s: string) -> Game {
ret: Game
rest := s[len("Game "):]
idOk: bool
idLen: int
ret.id, idOk = strconv.parse_int(rest, 10, &idLen)
rest = rest[idLen+len(": "):]
for len(rest) > 0 {
endOfRound := strings.index_rune(rest, ';')
if endOfRound == -1 do endOfRound = len(rest)
append(&ret.rounds, parse_round(rest[:endOfRound]))
rest = rest[min(endOfRound+1, len(rest)):]
}
return ret
}
is_game_possible :: proc(game: Game) -> bool {
for round in game.rounds {
if round.red > 12 ||
round.green > 13 ||
round.blue > 14 {
return false
}
}
return true
}
p1 :: proc(input: []string) {
totalIds := 0
for line in input {
game := parse_game(line)
defer delete(game.rounds)
if is_game_possible(game) do totalIds += game.id
}
fmt.println(totalIds)
}
p2 :: proc(input: []string) {
totalPower := 0
for line in input {
game := parse_game(line)
defer delete(game.rounds)
minRed := 0
minGreen := 0
minBlue := 0
for round in game.rounds {
minRed = max(minRed , round.red )
minGreen = max(minGreen, round.green)
minBlue = max(minBlue , round.blue )
}
totalPower += minRed * minGreen * minBlue
}
fmt.println(totalPower)
}
The thing that finally got businesses to finally get off IE wasn't from the browser being worse than every other option. Heck, it wasn't even because it was a decrepit piece of software that lost it's former market dominance (and if anything businesses see that as a positive, not a negative).
What finally did that was microsoft saying there won't be any security updates. That's what finally got them off their ass; subtly threatening them with data breaches, exploits, etc. if they continue to use it. I don't see google doing this anytime soon, at least not without a "sequel" like microsoft had with edge.