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)
}
Did this in Odin (very hashed together, especially finding the last number in part 2):
spoiler
package day1
import "core:fmt"
import "core:strings"
import "core:strconv"
import "core:unicode"
p1 :: proc(input: []string) {
total := 0
for line in input {
firstNum := line[strings.index_proc(line, unicode.is_digit):][:1]
lastNum := line[strings.last_index_proc(line, unicode.is_digit):][:1]
calibrationValue := strings.concatenate({firstNum, lastNum})
defer delete(calibrationValue)
num, ok := strconv.parse_int(calibrationValue)
total += num
}
// daggonit thought it was the whole numbers
/*
for line in input {
firstNum := line
fFrom := strings.index_proc(firstNum, unicode.is_digit)
firstNum = firstNum[fFrom:]
fTo := strings.index_proc(firstNum, proc(r:rune)->bool {return !unicode.is_digit(r)})
if fTo == -1 do fTo = len(firstNum)
firstNum = firstNum[:fTo]
lastNum := line
lastNum = lastNum[:strings.last_index_proc(lastNum, unicode.is_digit)+1]
lastNum = lastNum[strings.last_index_proc(lastNum, proc(r:rune)->bool {return !unicode.is_digit(r)})+1:]
calibrationValue := strings.concatenate({firstNum, lastNum})
defer delete(calibrationValue)
num, ok := strconv.parse_int(calibrationValue, 10)
if !ok {
fmt.eprintf("%s could not be parsed from %s", calibrationValue, line)
return
}
total += num;
}
*/
fmt.println(total)
}
p2 :: proc(input: []string) {
parse_wordable :: proc(s: string) -> int {
if len(s) == 1 {
num, ok := strconv.parse_int(s)
return num
} else do switch s {
case "one" : return 1
case "two" : return 2
case "three": return 3
case "four" : return 4
case "five" : return 5
case "six" : return 6
case "seven": return 7
case "eight": return 8
case "nine" : return 9
}
return -1
}
total := 0
for line in input {
firstNumI, firstNumW := strings.index_multi(line, {
"one" , "1",
"two" , "2",
"three", "3",
"four" , "4",
"five" , "5",
"six" , "6",
"seven", "7",
"eight", "8",
"nine" , "9",
})
firstNum := line[firstNumI:][:firstNumW]
// last_index_multi doesn't seem to exist, doing this as backup
lastNumI, lastNumW := -1, -1
for {
nLastNumI, nLastNumW := strings.index_multi(line[lastNumI+1:], {
"one" , "1",
"two" , "2",
"three", "3",
"four" , "4",
"five" , "5",
"six" , "6",
"seven", "7",
"eight", "8",
"nine" , "9",
})
if nLastNumI == -1 do break
lastNumI += nLastNumI+1
lastNumW = nLastNumW
}
lastNum := line[lastNumI:][:lastNumW]
total += parse_wordable(firstNum)*10 + parse_wordable(lastNum)
}
fmt.println(total)
}
Had a ton of trouble with part 1 until I realized I misinterpreted it. Especially annoying because the example was working fine. So paradoxically part 2 was easier than 1.
I don't think this can really be answered until after the fact. Anything that I (and I suspect most) people could say about an artstyle are going to be particular to an instance of that artsyle. If I'd give advice as someone who is neither an artist nor a game designer, what attracts me more than anything is a unique artstyle, which, if I'm gonna give a brutal opinion, starting from a vague category like 'pixel', 'hand drawn' or '3D' probably won't get you there.
I feel like I even struggle to answer your question at face value because it doesn't align well at all with how I conceptualize game art. For example, Cruelty Squad is a game that I don't think I'd have gotten if not for it's artsyle. Like, sure, it's 3D, but it's a lot more like a PilotRedSun animation than it is a game like TF2. Or take a game like Factorio: most of the assets of that game are pre-rendered 3D sprites, so despite being artisticly unique in a way that interests me it doesn't fit into the categories you've asked about. The best I can say is "I dunno", and I don't think anyone else can answer it further than that.
Found a potentially cool place to build on the server
Coords (if it's too hard to read from the image): -945, 312
I just saw the second clue and realized the stuff I've been building might cause some misdirection. Guessing that clue will be harder to figure out than intended 🤷.
To be fair, that post specifically asks people who don't have a technical background. It can be used to show that laymen have the capacity to use a federated platform like lemmy, but not that they are a significant portion of the userbase (albeit that post does have a lot of replies).
One library I've become very fond of using is Raylib. It has a ridiculously simple interface. If you just want to program a game and don't want/need the details of OpenGL/Vulkan/DirectX (which I'd suggest you do at some point anyways), then It'd be my pick.
It's a setting you can change. The default is a "quick generation" mode which looks as similar to the world seed/settings as it can without taking the performance hit of actually generating it. But it can either be changed to generate the chunks genuinely out to the render distance (which would be lag hell for 128 chunks) or to only render already generated chunks (like you suspect). Only the latter works in multiplayer though.
Huh. When I took Calculus II in community college, the professor introduced sum notation and like 2/3 of the class was like "wow that's cool I didn't know about that". I don't remember ever being formally taught it before that but it still surprises be how few people where already familiar with it.
I haven't actually. I'll go do that now.
Moving the cursor will confuse bash and you can get the same effect by just omitting the last \n.
When I was testing it I did not get the same effect. Instead it would only put the background behind what I had typed and not the whole line. Doing it now it seems to be working with the omission. I would assume it's a terminal emulator bug because I believe I have changed emulators since I wrote it. I've now removed it, thanks for fixing a bug.
Avoid doing external commands in subshells when there’s a perfectly good prompt-expansion string that works.
I wanted my home directory to not get shortened to ~
, and if there is some way to do that with \w
it isn't easy to find out how.
Also, what's the reasoning for avoiding it (besides it being idiomatic)? I'm sure there is one, but I don't think I've run into it yet.
You seem to be generating several unnecessary blank lines
I just like the look of it, and I have the screen space to do it.
I have this in my laptop's .bashrc
PS1='\e[0m\n\e[40m[\e[32m\u\e[37m] [\e[31m\A \d\e[31m] [\e[33m`pwd`\e[37m]\e[K\n\e[K\n\e[1A'
PS0='\e[0m\n'
hint
some of the escape sequences move the cursor
full explanation
generates the prompt:
[username] [00:01 Thu Jan 1] [/home/username]
█
with a slightly brighter/darker background (depending on terminal colors), while also resetting it to not effect the appearance of command outputs
\e[0m\n
: new blank line\e[40m
: sets the background color for the prompt[
: literal text\e[32m\u\e37m
: username in green, reset color for brackets] [
: literal text\e[31m\A \d\e[31m
: time/date in red, reset color] [
: literal text\e[33mpwd\e[37m
: calls pwd, prints it in orange]
: literal text\e[K\n
: fill the rest of the prompt line with the background\e[K\n
: fill the line where commands are typed with the background\e[1A
: move the cursor up so that it's in the background-filled area
I am colorblind so I may have gotten colors wrong, but that's hardly where the interesting bit is.
There is this excellent video which shows how a simple C program looks in assembly (don't worry about it being C, the program is simple enough to be understood without C knowledge). There's also this which does what the video shows automatically for you. Neither of these are fully sufficient to understand assembly but they are still incredibly useful resources.
Also: watch out for AT&T syntax vs Intel syntax if you're doing x86. It took me way to long to figure this out. And as another commenter mentioned look at TIS-100, but also some other similar games (sorted from easiest to hardest, TIS being harder than all of these): Human resource machine, EXAPUNKS, Shezhen I/O, and Box-256
I sent an application last night as notherealfluffy and I'm not whitelisted yet (albeit it hasn't been 24 hours). I'm a bit afraid that if it's being manually added to the list then whoever is doing that might attempt to fix what appears to be a typo but isn't.