Compare commits

...

10 Commits

Author SHA1 Message Date
m-hgn
eb5f3b18b7 add v version. 2023-05-01 23:49:29 +02:00
m-hgn
2864ba7771 make "all tests passed" message uniform 2023-05-01 23:49:11 +02:00
m-hgn
e41e696d46 add makefile used for all languages. 2023-05-01 22:00:25 +02:00
m-hgn
44fde4dfe8 add c version. 2023-05-01 21:59:41 +02:00
m-hgn
c189ec6010 add snail sort in odin. 2023-04-30 23:24:20 +02:00
m-hgn
d55bcf0599 add shebang to python script. 2023-04-23 22:12:34 +02:00
mark
6504f2c68d add python version. 2022-11-27 14:13:17 +01:00
mark
5373afb485 add d version. 2022-11-27 10:14:11 +01:00
mark
685eedcac9 add nim version. 2022-11-26 21:49:38 +01:00
mark
8393f06a14 add rust version. 2022-11-26 21:49:28 +01:00
8 changed files with 448 additions and 0 deletions

46
makefile Normal file
View File

@ -0,0 +1,46 @@
bd = ./build/
all: c d nim odin __python rust v
build-run: all
make run
run:
$(bd)c
$(bd)d
$(bd)nim
$(bd)odin
./snail.py
$(bd)rust
$(bd)v
clean:
rm -f $(bd)*
c: snail.c
gcc -Wall -Wextra -pedantic $^ -o $(bd)$@
$(bd)$@
d: snail.d
dmd $^ -of=$(bd)$@
$(bd)$@
nim: snail.nim
nim c $^ && mv snail $(bd)$@
$(bd)$@
odin: snail.odin
odin build . && mv *.bin $(bd)odin
$(bd)$@
__python: snail.py
python3 $^
rust: snail.rs
rustc $^ -o $(bd)$@
$(bd)$@
v: snail.v
v $^ -o $(bd)$@
$(bd)$@

68
snail.c Normal file
View File

@ -0,0 +1,68 @@
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
size_t max(const size_t*, const size_t*);
void snail(int* xss, int* yss, size_t h, size_t w) {
if (h == 0 || w == 0)
return;
int b, c, r, i = 0;
for (b = 0; b <= (int)max(&h, &w); b++) {
int ex = (w - b - 1), ey = (h - b - 1);
for (c = b; c <= ex; c++) yss[i++] = xss[b * w + c];
for (r = b + 1; r <= ey; r++) yss[i++] = xss[r * w + ex];
if (ex == b || ey == b) return;
for (c = ex - 1; c >= b; c--) yss[i++] = xss[ey * w + c];
for (r = ey - 1; r > b; r--) yss[i++] = xss[r * w + b];
}
}
size_t max(const size_t *a, const size_t *b) { return (*a < *b ? *b : *a); }
bool validate(int* res, int* exp, size_t len) {
bool valid = true;
for (size_t i = 0; i < len; i++) {
if (res[i] != exp[i]) {
valid = false;
break;
}
}
printf(valid ? "true\n" : "false\n");
return valid;
}
int main(void) {
bool all_valid = true;
int initial1[3*3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int expected1[sizeof(initial1)] = {1, 2, 3, 6, 9, 8, 7, 4, 5};
int* result = malloc(sizeof(initial1));
snail(initial1, result, 3, 3);
all_valid &= validate(result, expected1, sizeof(initial1) / sizeof(int));
free(result);
int initial2[3 * 4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int expected2[3 * 4] = {1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7};
result = malloc(sizeof(initial2));
snail(initial2, result, 3, 4);
all_valid &= validate(result, expected2, sizeof(initial2) / sizeof(int));
free(result);
int initial3[5 * 3] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int expected3[5 * 3] = {1, 2, 3, 6, 9, 12, 15, 14, 13, 10, 7, 4, 5, 8, 11};
result = malloc(sizeof(initial3));
snail(initial3, result, 5, 3);
all_valid &= validate(result, expected3, sizeof(initial3) / sizeof(int));
free(result);
printf(all_valid ? "all tests passed\n" : "tests failed\n");
return 0;
}

61
snail.d Normal file
View File

@ -0,0 +1,61 @@
import std.stdio;
import std.algorithm;
T[] snail(T)(T[][] xss)
{
ulong h = xss.length;
if (h == 0) { return []; }
ulong w = xss[0].length;
if (w == 0) { return []; }
T[] v = [];
foreach (b; 0..((max(w, h) / 2)+1)) {
ulong ex = w - b - 1;
ulong ey = h - b - 1;
foreach (c; b..ex+1)
v ~= [xss[b][c]];
foreach (r; b+1..ey+1)
v ~= [xss[r][ex]];
if (ex == b || ey == b) {
return v;
}
foreach (o; b..ex)
v ~= [xss[ey][ex-1-o]];
foreach (o; b+1..ey)
v ~= [xss[ey-o][b]];
}
return v;
}
void main()
{
int[][] initial = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
int[] expected = [1,2,3,6,9,8,7,4,5];
assert(snail(initial) == expected);
writeln(snail(initial) == expected);
initial = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
expected = [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7];
assert(snail(initial) == expected);
writeln(snail(initial) == expected);
initial = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12],
[13, 14, 15]
];
expected = [1, 2, 3, 6, 9, 12, 15, 14, 13, 10, 7, 4, 5, 8, 11];
assert(snail(initial) == expected);
writeln(snail(initial) == expected);
"all tests passed".writeln;
}

62
snail.nim Normal file
View File

@ -0,0 +1,62 @@
proc snail(xss: seq[seq[int]]): seq[int] =
let h = len(xss)
if h == 0:
return @[]
let w = len(xss[0])
if h == 0:
return @[]
let max = if h > w:
h
else:
w
var v: seq[int] = @[]
for b in 0..(max div 2):
let ex = w - b - 1;
let ey = h - b - 1;
for c in b..ex:
v.add(xss[b][c])
for r in b+1..ey:
v.add(xss[r][ex])
if ex == b or ey == b:
return v
for o in b..<ex:
v.add(xss[ey][ex-1-o])
for o in b+1..<ey:
v.add(xss[ey-o][b])
return v
var initial = @[@[1,2,3],@[4,5,6],@[7,8,9]]
var expected = @[1,2,3,6,9,8,7,4,5]
assert expected == snail(initial)
echo expected == snail(initial)
initial = @[@[1, 2, 3, 4], @[5, 6, 7, 8], @[9, 10, 11, 12]]
expected = @[1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]
assert expected == snail(initial)
echo expected == snail(initial)
initial = @[
@[1, 2, 3],
@[4, 5, 6],
@[7, 8, 9],
@[10, 11, 12],
@[13, 14, 15]
]
expected = @[1, 2, 3, 6, 9, 12, 15, 14, 13, 10, 7, 4, 5, 8, 11]
assert expected == snail(initial)
echo expected == snail(initial)
echo "all tests passed"

51
snail.odin Normal file
View File

@ -0,0 +1,51 @@
package main
import "core:fmt"
snail :: proc(xss: [][]int) -> [dynamic]int {
yss := [dynamic]int{}
h := len(xss)
if h == 0 { return yss }
w := len(xss[0])
if w == 0 { return yss }
for b in 0..=max(h, w) {
ex := w - b - 1
ey := h - b - 1
for c in b..=ex { append(&yss, xss[b][c]) }
for r in (b + 1)..=ey { append(&yss, xss[r][ex]) }
if ex == b || ey == b { return yss }
for c_off in b..<ex { append(&yss, xss[ey][ex - 1 - c_off]) }
for r_off in (b + 1)..<ey { append(&yss, xss[ey - r_off][b]) }
}
return yss
}
eq :: proc(a: []$T, b: []$S) -> bool {
if len(a) != len(b) { return false }
for i in 0..<len(a) {
if a[i] != b[i] { return false }
}
return true
}
main :: proc() {
initial := [][]int{ {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }
expected := [dynamic]int{1, 2, 3, 6, 9, 8, 7, 4, 5}
fmt.println(eq(snail(initial)[:], expected[:]))
initial = [][]int{ {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }
expected = {1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7}
fmt.println(eq(snail(initial)[:], expected[:]))
initial = [][]int{ {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}, {13, 14, 15} }
expected = [dynamic]int{1, 2, 3, 6, 9, 12, 15, 14, 13, 10, 7, 4, 5, 8, 11}
fmt.println(eq(snail(initial)[:], expected[:]))
fmt.println("all tests passed")
}

55
snail.py Normal file
View File

@ -0,0 +1,55 @@
#!/bin/env python3
def snail(xss):
h = len(xss)
w = len(xss[0])
if h == 0 or w == 0:
return []
v = []
for b in range(0, max(w, h) + 1):
ex = w - b - 1
ey = h - b - 1
for c in range(b, ex+1):
v.append(xss[b][c])
for r in range(b+1, ey+1):
v.append(xss[r][ex])
if ex == b or ey == b:
return v
for c in range(ex-1, b-1, -1):
v.append(xss[ey][c])
for r in range(ey-1, b, -1):
v.append(xss[r][b])
return v
initial = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
expected = [1, 2, 3, 6, 9, 8, 7, 4, 5]
assert(snail(initial) == expected)
print(snail(initial) == expected)
initial = [[1,2,3,4], [5,6,7,8], [9,10,11,12]]
expected = [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]
assert(snail(initial) == expected)
print(snail(initial) == expected)
initial = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12],
[13, 14, 15]
]
expected = [1, 2, 3, 6, 9, 12, 15, 14, 13, 10, 7, 4, 5, 8, 11]
assert(snail(initial) == expected)
print(snail(initial) == expected)
print("all tests passed")

56
snail.rs Normal file
View File

@ -0,0 +1,56 @@
fn snail<T>(xss: &[Vec<T>]) -> Vec<T>
where
T: Copy,
{
let h: usize = xss.len();
let w: usize = xss.get(0).map(Vec::len).unwrap_or(0);
if w == 0 || h == 0 {
return Vec::new();
}
(0..=(h.max(w) / 2)).fold(Vec::with_capacity(w * h), |mut v, b| {
let ex = w - b - 1;
let ey = h - b - 1;
let it = (b..=ex)
.map(|c| xss[b][c])
.chain(((b + 1)..=ey).map(|r| xss[r][ex]));
if ex == b || ey == b {
v.extend(it);
v
} else {
v.extend(
it.chain((b..ex).rev().map(|c| xss[ey][c]))
.chain(((b + 1)..ey).rev().map(|r| xss[r][b])),
);
v
}
})
}
fn main() {
let initial = &[vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
let expected = vec![1, 2, 3, 6, 9, 8, 7, 4, 5];
assert_eq!(expected, snail(initial));
println!("{}", expected == snail(initial));
let initial = &[vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
let expected = vec![1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7];
assert_eq!(expected, snail(initial));
println!("{}", expected == snail(initial));
let initial = &[
vec![1, 2, 3],
vec![4, 5, 6],
vec![7, 8, 9],
vec![10, 11, 12],
vec![13, 14, 15],
];
let expected = vec![1, 2, 3, 6, 9, 12, 15, 14, 13, 10, 7, 4, 5, 8, 11];
assert_eq!(expected, snail(initial));
println!("{}", expected == snail(initial));
println!("all tests passed");
}

49
snail.v Normal file
View File

@ -0,0 +1,49 @@
fn (xss [][]int) snail() []int {
mut ys := []int{}
h := xss.len
if h == 0 { return ys }
w := xss[0].len
if w == 0 { return ys }
for b in 0 .. (max(h, w)) {
ex := w - b - 1
ey := h - b - 1
for c in b .. (ex + 1) { ys << xss[b][c] }
for r in (b + 1) .. (ey + 1) { ys << xss[r][ex] }
if ex == b || ey == b { return ys }
for c in (b + 1) .. (ex + 1) { ys << xss[ey][ex - c] }
for r in (b + 1) .. ey { ys << xss[ey - r][b] }
}
return ys
}
fn max(a int, b int) int { if a > b { return a } else { return b } }
fn main() {
mut initial := [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
mut expected := [1, 2, 3, 6, 9, 8, 7, 4, 5]
assert initial.snail() == expected
println(initial.snail() == expected)
initial = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
expected = [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]
assert initial.snail() == expected
println(initial.snail() == expected)
initial = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12],
[13, 14, 15]
]
expected = [1, 2, 3, 6, 9, 12, 15, 14, 13, 10, 7, 4, 5, 8, 11]
assert initial.snail() == expected
println(initial.snail() == expected)
println('all tests passed')
}