Data update
This commit is contained in:
parent
4d5544505c
commit
4924dd0264
3073 changed files with 55820 additions and 4408 deletions
|
|
@ -1,17 +0,0 @@
|
|||
BEGIN {
|
||||
for(i=1; i <= 100; i++)
|
||||
{
|
||||
doors[i] = 0 # close the doors
|
||||
}
|
||||
for(i=1; i <= 100; i++)
|
||||
{
|
||||
for(j=i; j <= 100; j += i)
|
||||
{
|
||||
doors[j] = (doors[j]+1) % 2
|
||||
}
|
||||
}
|
||||
for(i=1; i <= 100; i++)
|
||||
{
|
||||
print i, doors[i] ? "open" : "close"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
BEGIN {
|
||||
for(i=1; i <= 100; i++) {
|
||||
doors[i] = 0 # close the doors
|
||||
}
|
||||
for(i=1; i <= 100; i++) {
|
||||
if ( int(sqrt(i)) == sqrt(i) ) {
|
||||
doors[i] = 1
|
||||
}
|
||||
}
|
||||
for(i=1; i <= 100; i++)
|
||||
{
|
||||
print i, doors[i] ? "open" : "close"
|
||||
}
|
||||
}
|
||||
16
Task/100-doors/Adina/100-doors-1.adina
Normal file
16
Task/100-doors/Adina/100-doors-1.adina
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
двери = новый-массив 100 ложь
|
||||
|
||||
цикл
|
||||
шаг
|
||||
в-диапазоне 1 101
|
||||
цикл
|
||||
номер
|
||||
в-диапазоне (шаг - 1) 100 шаг
|
||||
двери[номер] := не двери[номер]
|
||||
|
||||
цикл
|
||||
номер 100
|
||||
вывести/перенос
|
||||
формат «Дверь ~a ~a»
|
||||
номер + 1
|
||||
двери[номер] ? «открыта» «закрыта»
|
||||
17
Task/100-doors/Adina/100-doors-2.adina
Normal file
17
Task/100-doors/Adina/100-doors-2.adina
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
english()
|
||||
doors = make-vector 100 #f
|
||||
|
||||
for
|
||||
$ step
|
||||
in-range 1 101
|
||||
for
|
||||
$ number
|
||||
in-range (step - 1) 100 step
|
||||
doors[number] := not doors[number]
|
||||
|
||||
for
|
||||
$ number 100
|
||||
displayln
|
||||
format "Door ~a ~a"
|
||||
number + 1
|
||||
if doors[number] "open" "closed"
|
||||
21
Task/100-doors/ArkScript/100-doors-1.ark
Normal file
21
Task/100-doors/ArkScript/100-doors-1.ark
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
(import std.Range :range :forEach)
|
||||
(import std.List)
|
||||
|
||||
(mut doors (list:fill 100 false))
|
||||
(let r (range 0 100))
|
||||
|
||||
(forEach r
|
||||
(fun (i) {
|
||||
(mut j i)
|
||||
(while (< j 100) {
|
||||
(@= doors j (not (@ doors j)))
|
||||
(set j (+ j i 1)) })
|
||||
(print doors) }))
|
||||
|
||||
(print
|
||||
(list:map
|
||||
(list:filter
|
||||
(list:zipWithIndex doors)
|
||||
(fun (e)
|
||||
(@ e 1)))
|
||||
(fun (e) (@ e 0))))
|
||||
4
Task/100-doors/ArkScript/100-doors-2.ark
Normal file
4
Task/100-doors/ArkScript/100-doors-2.ark
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
[true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true]
|
||||
...
|
||||
[true false false true false false false false true false false false false false false true false false false false false false false false true false false false false false false false false false false true false false false false false false false false false false false false true false false false false false false false false false false false false false false true false false false false false false false false false false false false false false false false true false false false false false false false false false false false false false false false false false false true]
|
||||
[0 3 8 15 24 35 48 63 80 99]
|
||||
18
Task/100-doors/AutoLISP/100-doors.l
Normal file
18
Task/100-doors/AutoLISP/100-doors.l
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
(defun CreateDoors (n / doors)
|
||||
(repeat n
|
||||
(setq doors (cons nil doors))
|
||||
)
|
||||
)
|
||||
|
||||
(defun Doors (doors / cnt)
|
||||
(setq cnt 0)
|
||||
(mapcar
|
||||
'(lambda (d)
|
||||
(zerop (rem (sqrt (setq cnt (1+ cnt))) 1))
|
||||
)
|
||||
doors
|
||||
)
|
||||
)
|
||||
|
||||
> (Doors (CreateDoors 100))
|
||||
(T nil nil T nil nil nil nil T nil nil nil nil nil nil T nil nil nil nil nil nil nil nil T nil nil nil nil nil nil nil nil nil nil T nil nil nil nil nil nil nil nil nil nil nil nil T nil nil nil nil nil nil nil nil nil nil nil nil nil nil T nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil T nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil T nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil T nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil T nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil T nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil T nil nil nil nil)
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
MODULE Doors100;
|
||||
IMPORT StdLog;
|
||||
|
||||
PROCEDURE Do*;
|
||||
VAR
|
||||
i,j: INTEGER;
|
||||
closed: ARRAY 101 OF BOOLEAN;
|
||||
BEGIN
|
||||
(* initialization of closed to true *)
|
||||
FOR i := 0 TO LEN(closed) - 1 DO closed[i] := TRUE END;
|
||||
(* process *)
|
||||
FOR i := 1 TO LEN(closed) DO;
|
||||
j := 1;
|
||||
WHILE j < LEN(closed) DO
|
||||
IF j MOD i = 0 THEN closed[j] := ~closed[j] END;INC(j)
|
||||
END
|
||||
END;
|
||||
(* print results *)
|
||||
i := 1;
|
||||
WHILE i < LEN(closed) DO
|
||||
IF (i - 1) MOD 10 = 0 THEN StdLog.Ln END;
|
||||
IF closed[i] THEN StdLog.String("C ") ELSE StdLog.String("O ") END;
|
||||
INC(i)
|
||||
END;
|
||||
END Do;
|
||||
END Doors100.
|
||||
19
Task/100-doors/DuckDB/100-doors.duckdb
Normal file
19
Task/100-doors/DuckDB/100-doors.duckdb
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Show the state of n doors after n iterations
|
||||
create or replace function doors(n) as (
|
||||
with recursive cte(ix,d) as (
|
||||
select 0 as ix, list_transform(range(0, n), x -> false) as d
|
||||
union all
|
||||
select ix+1,
|
||||
list_transform(d, (x,i) -> if (i % (ix + 1) = 0, NOT x, x))
|
||||
from cte
|
||||
where ix < n
|
||||
)
|
||||
select last(d order by ix)
|
||||
from cte
|
||||
);
|
||||
|
||||
# For brevity, we just show the indices of the doors that are open after all
|
||||
# have been visited:
|
||||
select ix
|
||||
from (select unnest(generate_series(1,100)) as ix, unnest(doors(100)) as d)
|
||||
where d = true;
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
gate :: Eq a => [a] -> [a] -> [Door]
|
||||
gate (x:xs) (y:ys) | x == y = Open : gate xs ys
|
||||
gate (x:xs) ys = Closed : gate xs ys
|
||||
gate [] _ = []
|
||||
isDoorOpen :: Integral a => a -> Bool
|
||||
-- In Haskell, we are too lazy to open and close doors. Instead we
|
||||
-- count how many times we would have toggled them, and then check if
|
||||
-- that number is odd.
|
||||
isDoorOpen doorNumber = odd numToggles
|
||||
where numToggles = length [ 1 | x <- [1..doorNumber], doorNumber `rem` x == 0]
|
||||
|
||||
run n = gate [1..n] [k*k | k <- [1..]]
|
||||
main = do
|
||||
print $ "Open doors are " ++ show [x | x <- [0..100], isDoorOpen x]
|
||||
|
|
|
|||
|
|
@ -1 +1,6 @@
|
|||
run n = takeWhile (< n) [k*k | k <- [1..]]
|
||||
gate :: Eq a => [a] -> [a] -> [Door]
|
||||
gate (x:xs) (y:ys) | x == y = Open : gate xs ys
|
||||
gate (x:xs) ys = Closed : gate xs ys
|
||||
gate [] _ = []
|
||||
|
||||
run n = gate [1..n] [k*k | k <- [1..]]
|
||||
|
|
|
|||
1
Task/100-doors/Haskell/100-doors-5.hs
Normal file
1
Task/100-doors/Haskell/100-doors-5.hs
Normal file
|
|
@ -0,0 +1 @@
|
|||
run n = takeWhile (< n) [k*k | k <- [1..]]
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
local is_open = {}
|
||||
|
||||
for pass = 1,100 do
|
||||
for door = pass,100,pass do
|
||||
is_open[door] = not is_open[door]
|
||||
end
|
||||
end
|
||||
|
||||
for i,v in next,is_open do
|
||||
print ('Door '..i..':',v and 'open' or 'close')
|
||||
end
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
100H: /* FIND THE FIRST FEW SQUARES VIA THE UNOPTIMISED DOOR FLIPPING METHOD */
|
||||
|
||||
/* BDOS SYSTEM CALL */
|
||||
BDOS: PROCEDURE( FN, ARG );
|
||||
DECLARE FN BYTE, ARG ADDRESS;
|
||||
GO TO 5;
|
||||
END BDOS;
|
||||
|
||||
/* PRINTS A BYTE AS A CHARACTER */
|
||||
PRINT$CHAR: PROCEDURE( CH );
|
||||
DECLARE CH BYTE;
|
||||
CALL BDOS( 2, CH );
|
||||
END PRINT$CHAR;
|
||||
|
||||
/* PRINTS A BYTE AS A NUMBER */
|
||||
PRINT$BYTE: PROCEDURE( N );
|
||||
DECLARE N BYTE;
|
||||
DECLARE ( V, D3, D2 ) BYTE;
|
||||
V = N;
|
||||
D3 = V MOD 10;
|
||||
IF ( V := V / 10 ) <> 0 THEN DO;
|
||||
D2 = V MOD 10;
|
||||
IF ( V := V / 10 ) <> 0 THEN CALL PRINT$CHAR( '0' + V );
|
||||
CALL PRINT$CHAR( '0' + D2 );
|
||||
END;
|
||||
CALL PRINT$CHAR( '0' + D3 );
|
||||
END PRINT$BYTE;
|
||||
|
||||
DECLARE DOOR$DCL LITERALLY '101';
|
||||
DECLARE FALSE LITERALLY '0';
|
||||
DECLARE CR LITERALLY '0DH';
|
||||
DECLARE LF LITERALLY '0AH';
|
||||
|
||||
/* ARRAY OF DOORS - DOOR( I ) IS TRUE IF OPEN, FALSE IF CLOSED */
|
||||
DECLARE DOOR( DOOR$DCL ) BYTE;
|
||||
DECLARE ( I, J ) BYTE;
|
||||
|
||||
/* SET ALL DOORS TO CLOSED */
|
||||
DO I = 0 TO LAST( DOOR ); DOOR( I ) = FALSE; END;
|
||||
/* REPEATEDLY FLIP THE DOORS */
|
||||
DO I = 1 TO LAST( DOOR );
|
||||
DO J = I TO LAST( DOOR ) BY I;
|
||||
DOOR( J ) = NOT DOOR( J );
|
||||
END;
|
||||
END;
|
||||
/* DISPLAY THE RESULTS */
|
||||
DO I = 1 TO LAST( DOOR );
|
||||
IF DOOR( I ) THEN DO;
|
||||
CALL PRINT$CHAR( ' ' );
|
||||
CALL PRINT$BYTE( I );
|
||||
END;
|
||||
END;
|
||||
CALL PRINT$CHAR( CR );
|
||||
CALL PRINT$CHAR( LF );
|
||||
EOF
|
||||
|
|
@ -1,2 +1,26 @@
|
|||
doors: array/initial 100 'closed
|
||||
repeat i 10 [doors/(i * i): 'open]
|
||||
;; Create a bitset with capacity for 100 bits (representing 100 doors)
|
||||
;; Each bit represents a door state: 0 = closed, 1 = open
|
||||
doors: make bitset! 100
|
||||
|
||||
;; Outer loop: Make 100 passes (i = 1 to 100)
|
||||
repeat i 100 [
|
||||
;; Inner loop: Check each door position (j = 1 to 100)
|
||||
repeat j 100 [
|
||||
;; If door j index is divisible by pass number i (no remainder)
|
||||
if zero? (j // i) [
|
||||
;; Toggle the door's bit:
|
||||
;; doors/:j accesses door j in the bitset
|
||||
;; 'not' flips the bit value (0 -> 1, 1 -> 0)
|
||||
doors/:j: not doors/:j
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
;; Final loop: Check which doors are open, print their numbers
|
||||
repeat i 100 [
|
||||
;; If door i's bit is set (open)
|
||||
if doors/:i [
|
||||
;; Print the door's number and that it is open
|
||||
print ["door" i "is open"]
|
||||
]
|
||||
]
|
||||
|
|
|
|||
6
Task/100-doors/REBOL/100-doors-3.rebol
Normal file
6
Task/100-doors/REBOL/100-doors-3.rebol
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
;; Loop variable i from 1 to 10 (since 10^2 = 100, covers doors 1 to 100)
|
||||
repeat i 10 [
|
||||
;; Print that door number (i squared) is open
|
||||
;; These are exactly the doors with perfect square numbers: 1, 4, 9, ..., 100
|
||||
print ["door" (i * i) "is open"]
|
||||
]
|
||||
43
Task/100-prisoners/Prolog/100-prisoners.pro
Normal file
43
Task/100-prisoners/Prolog/100-prisoners.pro
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
:- use_module(library(aggregate)).
|
||||
:- use_module(library(lists)).
|
||||
:- use_module(library(random)).
|
||||
|
||||
random_subset(Length, List, Subset) :-
|
||||
random_permutation(List, Shuffled),
|
||||
length(Subset, Length),
|
||||
prefix(Subset, Shuffled).
|
||||
|
||||
random_play :-
|
||||
numlist(1, 100, Prisoners),
|
||||
random_permutation(Prisoners, Drawers),
|
||||
forall(member(Prisoner, Prisoners), (
|
||||
random_subset(50, Drawers, CheckedDrawers),
|
||||
memberchk(Prisoner, CheckedDrawers)
|
||||
)).
|
||||
|
||||
optimal_play :-
|
||||
numlist(1, 100, Prisoners),
|
||||
random_permutation(Prisoners, Drawers),
|
||||
forall(member(Prisoner, Prisoners), optimal_play(50, Prisoner, Prisoner, Drawers)).
|
||||
|
||||
optimal_play(ChecksRemaining, Prisoner, NumberToCheck, Drawers) :-
|
||||
ChecksRemaining > 0,
|
||||
nth1(NumberToCheck, Drawers, NumberInDrawer),
|
||||
( NumberInDrawer = Prisoner
|
||||
-> true
|
||||
; ChecksRemaining0 is ChecksRemaining - 1,
|
||||
optimal_play(ChecksRemaining0, Prisoner, NumberInDrawer, Drawers)
|
||||
).
|
||||
|
||||
:- meta_predicate play_n_times(+, 0, -).
|
||||
play_n_times(PlayCount, Play, Percentage) :-
|
||||
aggregate_all(count, ( between(1, PlayCount, _), call(Play) ), Victories),
|
||||
Percentage is Victories / PlayCount * 100.
|
||||
|
||||
main(SimulationCount) :-
|
||||
play_n_times(SimulationCount, random_play, RandomPlayPercent),
|
||||
play_n_times(SimulationCount, optimal_play, OptimalPlayPercent),
|
||||
format("Simulation count: ~d\nRandom play wins: ~f% of the simulations.\nOptimal play wins ~f% of the simulations.",
|
||||
[SimulationCount, RandomPlayPercent, OptimalPlayPercent]).
|
||||
|
||||
:- main(100_000).
|
||||
3
Task/15-puzzle-solver/PascalABC.NET/15-puzzle-solver.pas
Normal file
3
Task/15-puzzle-solver/PascalABC.NET/15-puzzle-solver.pas
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
// Игра в 15 PABCWork.NET\Samples\Games\15.pas
|
||||
see
|
||||
https://rosettacode.org/wiki/15_puzzle_game#PascalABC.NET
|
||||
|
|
@ -142,7 +142,7 @@ proc handle_mup .
|
|||
on mouse_up
|
||||
handle_mup
|
||||
.
|
||||
on key
|
||||
on key_down
|
||||
if stat = 2
|
||||
if keybkey = " " : init
|
||||
return
|
||||
|
|
|
|||
273
Task/24-game-Solve/Zig/24-game-solve.zig
Normal file
273
Task/24-game-Solve/Zig/24-game-solve.zig
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
const std = @import("std");
|
||||
const print = std.debug.print;
|
||||
const ArrayList = std.ArrayList;
|
||||
const HashMap = std.HashMap;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const Operator = enum {
|
||||
sub,
|
||||
plus,
|
||||
mul,
|
||||
div,
|
||||
};
|
||||
|
||||
const Factor = struct {
|
||||
content: []const u8,
|
||||
value: i32,
|
||||
|
||||
fn deinit(self: Factor, allocator: Allocator) void {
|
||||
allocator.free(self.content);
|
||||
}
|
||||
};
|
||||
|
||||
fn apply(allocator: Allocator, op: Operator, left: []const Factor, right: []const Factor) !ArrayList(Factor) {
|
||||
var ret = ArrayList(Factor).init(allocator);
|
||||
|
||||
for (left) |l| {
|
||||
for (right) |r| {
|
||||
switch (op) {
|
||||
.sub => {
|
||||
if (l.value > r.value) {
|
||||
const content = try std.fmt.allocPrint(allocator, "({s} - {s})", .{ l.content, r.content });
|
||||
try ret.append(Factor{
|
||||
.content = content,
|
||||
.value = l.value - r.value,
|
||||
});
|
||||
}
|
||||
},
|
||||
.plus => {
|
||||
const content = try std.fmt.allocPrint(allocator, "({s} + {s})", .{ l.content, r.content });
|
||||
try ret.append(Factor{
|
||||
.content = content,
|
||||
.value = l.value + r.value,
|
||||
});
|
||||
},
|
||||
.mul => {
|
||||
const content = try std.fmt.allocPrint(allocator, "({s} x {s})", .{ l.content, r.content });
|
||||
try ret.append(Factor{
|
||||
.content = content,
|
||||
.value = l.value * r.value,
|
||||
});
|
||||
},
|
||||
.div => {
|
||||
if (l.value >= r.value and r.value > 0 and @rem(l.value, r.value) == 0) {
|
||||
const content = try std.fmt.allocPrint(allocator, "({s} / {s})", .{ l.content, r.content });
|
||||
try ret.append(Factor{
|
||||
.content = content,
|
||||
.value = @divTrunc(l.value, r.value),
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
fn calc(allocator: Allocator, ops: [3]Operator, numbers: [4]i32) !ArrayList(Factor) {
|
||||
var current_factors = ArrayList(Factor).init(allocator);
|
||||
defer {
|
||||
for (current_factors.items) |factor| {
|
||||
factor.deinit(allocator);
|
||||
}
|
||||
current_factors.deinit();
|
||||
}
|
||||
|
||||
// Initialize with first number
|
||||
const initial_content = try std.fmt.allocPrint(allocator, "{}", .{numbers[0]});
|
||||
try current_factors.append(Factor{
|
||||
.content = initial_content,
|
||||
.value = numbers[0],
|
||||
});
|
||||
|
||||
// Process each operation
|
||||
for (ops, 0..) |op, i| {
|
||||
var next_factors = ArrayList(Factor).init(allocator);
|
||||
defer {
|
||||
for (next_factors.items) |factor| {
|
||||
factor.deinit(allocator);
|
||||
}
|
||||
next_factors.deinit();
|
||||
}
|
||||
|
||||
const mono_content = try std.fmt.allocPrint(allocator, "{}", .{numbers[i + 1]});
|
||||
defer allocator.free(mono_content);
|
||||
const mono_factor = Factor{
|
||||
.content = mono_content,
|
||||
.value = numbers[i + 1],
|
||||
};
|
||||
const mono_slice = &[_]Factor{mono_factor};
|
||||
|
||||
switch (op) {
|
||||
.mul, .plus => {
|
||||
var applied = try apply(allocator, op, current_factors.items, mono_slice);
|
||||
defer applied.deinit();
|
||||
try next_factors.appendSlice(applied.items);
|
||||
},
|
||||
.div, .sub => {
|
||||
var applied1 = try apply(allocator, op, current_factors.items, mono_slice);
|
||||
defer applied1.deinit();
|
||||
try next_factors.appendSlice(applied1.items);
|
||||
|
||||
var applied2 = try apply(allocator, op, mono_slice, current_factors.items);
|
||||
defer applied2.deinit();
|
||||
try next_factors.appendSlice(applied2.items);
|
||||
},
|
||||
}
|
||||
|
||||
// Clear current factors and move next_factors to current_factors
|
||||
for (current_factors.items) |factor| {
|
||||
factor.deinit(allocator);
|
||||
}
|
||||
current_factors.clearRetainingCapacity();
|
||||
|
||||
// Move ownership from next_factors to current_factors
|
||||
try current_factors.appendSlice(next_factors.items);
|
||||
next_factors.clearRetainingCapacity(); // Don't deinit the items, we moved them
|
||||
}
|
||||
|
||||
// Create result and transfer ownership
|
||||
var result = ArrayList(Factor).init(allocator);
|
||||
try result.appendSlice(current_factors.items);
|
||||
current_factors.clearRetainingCapacity(); // Don't deinit, we transferred ownership
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const OpIter = struct {
|
||||
index: usize,
|
||||
|
||||
const OPTIONS = [_]Operator{ .mul, .sub, .plus, .div };
|
||||
|
||||
fn init() OpIter {
|
||||
return OpIter{ .index = 0 };
|
||||
}
|
||||
|
||||
fn next(self: *OpIter) ?[3]Operator {
|
||||
if (self.index >= 64) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const f1 = OPTIONS[(self.index & (3 << 4)) >> 4];
|
||||
const f2 = OPTIONS[(self.index & (3 << 2)) >> 2];
|
||||
const f3 = OPTIONS[(self.index & (3 << 0)) >> 0];
|
||||
|
||||
self.index += 1;
|
||||
return [3]Operator{ f1, f2, f3 };
|
||||
}
|
||||
};
|
||||
|
||||
fn orders() [24][4]usize {
|
||||
return [24][4]usize{
|
||||
[4]usize{ 0, 1, 2, 3 },
|
||||
[4]usize{ 0, 1, 3, 2 },
|
||||
[4]usize{ 0, 2, 1, 3 },
|
||||
[4]usize{ 0, 2, 3, 1 },
|
||||
[4]usize{ 0, 3, 1, 2 },
|
||||
[4]usize{ 0, 3, 2, 1 },
|
||||
[4]usize{ 1, 0, 2, 3 },
|
||||
[4]usize{ 1, 0, 3, 2 },
|
||||
[4]usize{ 1, 2, 0, 3 },
|
||||
[4]usize{ 1, 2, 3, 0 },
|
||||
[4]usize{ 1, 3, 0, 2 },
|
||||
[4]usize{ 1, 3, 2, 0 },
|
||||
[4]usize{ 2, 0, 1, 3 },
|
||||
[4]usize{ 2, 0, 3, 1 },
|
||||
[4]usize{ 2, 1, 0, 3 },
|
||||
[4]usize{ 2, 1, 3, 0 },
|
||||
[4]usize{ 2, 3, 0, 1 },
|
||||
[4]usize{ 2, 3, 1, 0 },
|
||||
[4]usize{ 3, 0, 1, 2 },
|
||||
[4]usize{ 3, 0, 2, 1 },
|
||||
[4]usize{ 3, 1, 0, 2 },
|
||||
[4]usize{ 3, 1, 2, 0 },
|
||||
[4]usize{ 3, 2, 0, 1 },
|
||||
[4]usize{ 3, 2, 1, 0 },
|
||||
};
|
||||
}
|
||||
|
||||
fn applyOrder(numbers: [4]i32, order: [4]usize) [4]i32 {
|
||||
return [4]i32{ numbers[order[0]], numbers[order[1]], numbers[order[2]], numbers[order[3]] };
|
||||
}
|
||||
|
||||
fn solutions(allocator: Allocator, numbers: [4]i32) !ArrayList(Factor) {
|
||||
var ret = ArrayList(Factor).init(allocator);
|
||||
var hash_set = HashMap([]const u8, void, std.hash_map.StringContext, std.hash_map.default_max_load_percentage).init(allocator);
|
||||
defer {
|
||||
// Free all keys in the hash map
|
||||
var iterator = hash_set.iterator();
|
||||
while (iterator.next()) |entry| {
|
||||
allocator.free(entry.key_ptr.*);
|
||||
}
|
||||
hash_set.deinit();
|
||||
}
|
||||
|
||||
var op_iter = OpIter.init();
|
||||
while (op_iter.next()) |ops| {
|
||||
const all_orders = orders();
|
||||
for (all_orders) |order| {
|
||||
const reordered_numbers = applyOrder(numbers, order);
|
||||
var results = calc(allocator, ops, reordered_numbers) catch continue;
|
||||
defer {
|
||||
for (results.items) |factor| {
|
||||
factor.deinit(allocator);
|
||||
}
|
||||
results.deinit();
|
||||
}
|
||||
|
||||
for (results.items) |factor| {
|
||||
if (factor.value == 24) {
|
||||
// Check if we've seen this content before
|
||||
if (hash_set.contains(factor.content)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add to hash set with a duplicated key
|
||||
const key_copy = try allocator.dupe(u8, factor.content);
|
||||
try hash_set.put(key_copy, {});
|
||||
|
||||
// Add to results with a duplicated content
|
||||
try ret.append(Factor{
|
||||
.content = try allocator.dupe(u8, factor.content),
|
||||
.value = factor.value,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
// Hard-coded input: 5598
|
||||
const nums = [4]i32{ 5, 5, 9, 8 };
|
||||
|
||||
var sols = solutions(allocator, nums) catch {
|
||||
print("Error computing solutions\n", .{});
|
||||
return;
|
||||
};
|
||||
defer {
|
||||
for (sols.items) |factor| {
|
||||
factor.deinit(allocator);
|
||||
}
|
||||
sols.deinit();
|
||||
}
|
||||
|
||||
const len = sols.items.len;
|
||||
if (len == 0) {
|
||||
print("no solution for {}, {}, {}, {}\n", .{ nums[0], nums[1], nums[2], nums[3] });
|
||||
return;
|
||||
}
|
||||
|
||||
print("solutions for {}, {}, {}, {}\n", .{ nums[0], nums[1], nums[2], nums[3] });
|
||||
for (sols.items) |s| {
|
||||
print("{s}\n", .{s.content});
|
||||
}
|
||||
print("{} solutions found\n", .{len});
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
include resources "24 Game Icon.icns"
|
||||
//include resources "24 Game Icon.icns"
|
||||
|
||||
#build CompilerOptions @"-Wno-unused-variable"
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ fn to_rpn(input: &mut String){
|
|||
rpn_string.push(top);
|
||||
}
|
||||
|
||||
println!("you formula results in {}", rpn_string);
|
||||
println!("your formula results in {}", rpn_string);
|
||||
|
||||
*input=rpn_string;
|
||||
}
|
||||
|
|
@ -72,7 +72,7 @@ fn calculate(input: &String, list : &mut [u32;4]) -> f32{
|
|||
};
|
||||
}
|
||||
}
|
||||
println!("you formula results in {}",accumulator);
|
||||
println!("your formula results in {}",accumulator);
|
||||
accumulator
|
||||
}
|
||||
|
||||
|
|
@ -95,14 +95,14 @@ fn main() {
|
|||
to_rpn(&mut input);
|
||||
let result = calculate(&input, &mut list);
|
||||
|
||||
if list.iter().any(|&list| list !=10){
|
||||
if list.iter().any(|&num| num != 10) {
|
||||
println!("you didn't use all the numbers");
|
||||
} else {
|
||||
println!("and you used all numbers");
|
||||
match result {
|
||||
24.0 => println!("you won"),
|
||||
_ => println!("but your formulla doesn't result in 24"),
|
||||
_ => println!("but your formula doesn't result in 24"),
|
||||
}
|
||||
}else{
|
||||
println!("you didn't use all the numbers");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
Rebol [
|
||||
title: "Rosetta code: 9 billion names of God the integer"
|
||||
file: %9_billion_names_of_God_the_integer.r3
|
||||
url: https://rosettacode.org/wiki/9_billion_names_of_God_the_integer
|
||||
needs: 3.0.0
|
||||
note: {Based on Red language version}
|
||||
]
|
||||
names-of-god: function/with [
|
||||
row [integer!] "row number (>= 1)"
|
||||
/show "Display intermediate results"
|
||||
/all "When showing, print all intermediate data"
|
||||
][
|
||||
;; Validate input - require row >= 1, otherwise trigger a runtime error
|
||||
assert [row >= 1]
|
||||
|
||||
;; If /show refinement is used, display results for the given row
|
||||
if show [
|
||||
;; Ensure nums/:row is computed; if not, recursively compute it
|
||||
unless nums/:row [names-of-god row]
|
||||
|
||||
;; Loop from 1 to row
|
||||
repeat i row [
|
||||
either all [ ;; If /all refinement is used, display extra details
|
||||
probe reduce [i nums/:i sums/:i] ;; Show index, sequence, and sum
|
||||
][
|
||||
print nums/:i ;; Otherwise, just print the sequence
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
;; Compute a new row from scratch (if row not already computed)...
|
||||
unless sum: sums/:row [
|
||||
out: clear [] ;; Temporary storage for row's elements
|
||||
half: to integer! row / 2 ;; Middle position of the row
|
||||
|
||||
;; Ensure all required previous rows exist; generate missing ones
|
||||
if row - 1 > last: length? nums [
|
||||
repeat i row - last - 1 [
|
||||
names-of-god last + i
|
||||
]
|
||||
]
|
||||
|
||||
;; Build the `out` block for this row
|
||||
repeat col row - 1 [
|
||||
;; Special case: the middle element
|
||||
either col = (half + 1) [
|
||||
append out at nums/(row - 1) half ;; Insert from previous row's middle
|
||||
break ;; Stop building here
|
||||
][
|
||||
;; General case: append sum-part of two earlier sequences
|
||||
append out sum-part nums/(row - col) col
|
||||
]
|
||||
]
|
||||
|
||||
;; Compute the sum of the row
|
||||
sum: 0.0
|
||||
forall out [
|
||||
sum: sum + out/1
|
||||
]
|
||||
|
||||
;; Cache the computed row and its sum
|
||||
sums/:row: sum
|
||||
nums/:row: copy out
|
||||
clear out
|
||||
]
|
||||
sums/:row ;; Return sum of the row
|
||||
][
|
||||
;; ===== WITH BLOCK (local helper definitions and persistent state) =====
|
||||
|
||||
;; Helper function: sum the first `count` elements from the given block `nums`
|
||||
sum-part: function [nums [block!] count [integer!]][
|
||||
out: 0.0
|
||||
loop count [
|
||||
out: out + nums/1
|
||||
if empty? nums: next nums [break] ;; Stop if we've exhausted the block
|
||||
]
|
||||
;; If within integer range, convert to integer
|
||||
if out <= 0#7fffffffffffffff [out: to integer! out]
|
||||
out
|
||||
]
|
||||
|
||||
;; Persistent storage for each computed row (map! with row → sequence)
|
||||
;; Start with base cases:
|
||||
;; row 1 = [1]
|
||||
;; row 2 = [1 1]
|
||||
nums: make map! [1 [1] 2 [1 1]]
|
||||
|
||||
;; Persistent storage for row sums (map! with row → sum)
|
||||
;; Base sums: row 1 sum = 1, row 2 sum = 2
|
||||
sums: make map! [1 1 2 2]
|
||||
]
|
||||
|
||||
|
||||
|
||||
print "rows: ^/"
|
||||
names-of-god/show 25
|
||||
|
||||
print "^/sums: ^/"
|
||||
probe names-of-god 23
|
||||
probe names-of-god 123
|
||||
probe names-of-god 1234
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
main:(
|
||||
FOR bottles FROM 99 TO 1 BY -1 DO
|
||||
printf(($z-d" bottles of beer on the wall"l$, bottles));
|
||||
printf(($z-d" bottles of beer"l$, bottles));
|
||||
printf(($"Take one down, pass it around"l$));
|
||||
printf(($z-d" bottles of beer on the wall"ll$, bottles-1))
|
||||
OD
|
||||
)
|
||||
FOR bottles FROM 99 BY -1 TO 1 DO
|
||||
STRING bottles now = whole(bottles,0) + " bottle" + IF bottles = 1 THEN "" ELSE "s" FI;
|
||||
STRING bottles left = IF bottles = 1 THEN "No more" ELSE whole(bottles-1,0) FI
|
||||
+ " bottle"
|
||||
+ IF bottles = 2 THEN "" ELSE "s" FI;
|
||||
print((bottles now," of beer on the wall",newline));
|
||||
print((bottles now," of beer",newline));
|
||||
print(("Take one down, pass it around",newline));
|
||||
print((bottles left," of beer on the wall",newline,newline))
|
||||
OD
|
||||
|
|
|
|||
48
Task/99-bottles-of-beer/Aria/99-bottles-of-beer.aria
Normal file
48
Task/99-bottles-of-beer/Aria/99-bottles-of-beer.aria
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
struct Lyrics {
|
||||
type func new(n: Int) {
|
||||
assert n > 0;
|
||||
return alloc(This) {
|
||||
.n = n,
|
||||
};
|
||||
}
|
||||
|
||||
func prettyprint() {
|
||||
val suffix_n = this.n == 1 ? "" : "s";
|
||||
val suffix_n_minus_1 = this.n == 2 ? "" : "s";
|
||||
return "{0} bottle{2} of beer on the wall, {0} bottle{2} of beer.\nTake one down and pass it around, {1} bottle{3} of beer on the wall.\n".format(this.n, this.n-1, suffix_n, suffix_n_minus_1);
|
||||
}
|
||||
}
|
||||
|
||||
struct Song {
|
||||
type func new(n: Int) {
|
||||
assert n > 0;
|
||||
return alloc(This) {
|
||||
.n = n,
|
||||
};
|
||||
}
|
||||
|
||||
func iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
func next() {
|
||||
if this.n == 0 {
|
||||
return Box(){.done = true};
|
||||
}
|
||||
|
||||
val n = this.n;
|
||||
this.n -= 1;
|
||||
|
||||
return Box() {
|
||||
.done = false,
|
||||
.value = Lyrics.new(n),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
val song = Song.new(99);
|
||||
for verse in song {
|
||||
println(verse);
|
||||
}
|
||||
}
|
||||
24
Task/99-bottles-of-beer/ArkScript/99-bottles-of-beer.ark
Normal file
24
Task/99-bottles-of-beer/ArkScript/99-bottles-of-beer.ark
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# try and get an argument from the command line invocation
|
||||
(let arg
|
||||
(if (>= (len sys:args) 1)
|
||||
(toNumber (@ sys:args 0))
|
||||
nil))
|
||||
# if no argument was passed the default value will be 100
|
||||
(let i
|
||||
(if (nil? arg)
|
||||
100
|
||||
arg))
|
||||
|
||||
(let explode-bottles (fun (n)
|
||||
(if (> n 1) {
|
||||
(print (string:format "{} Bottles of beer on the wall\n{} bottles of beer\nTake one down, pass it around" n n))
|
||||
(print (string:format "{} Bottles of beer on the wall." (- n 1)))
|
||||
(explode-bottles (- n 1)) })
|
||||
(explode-bottles i)
|
||||
|
||||
# alternative solution with a loop
|
||||
(mut n i)
|
||||
(while (> n 1) {
|
||||
(print (string:format "{} Bottles of beer on the wall\n{} bottles of beer\nTake one down, pass it around" n n))
|
||||
(set n (- n 1))
|
||||
(print (string:format "{} Bottles of beer on the wall." n)) })
|
||||
13
Task/99-bottles-of-beer/DuckDB/99-bottles-of-beer-1.duckdb
Normal file
13
Task/99-bottles-of-beer/DuckDB/99-bottles-of-beer-1.duckdb
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
.header off
|
||||
.mode list
|
||||
select list_transform( range(99,-1,-1),
|
||||
n ->
|
||||
if (n = 0,
|
||||
'No more bottles of beer on the wall' || chr(10)
|
||||
|| 'no more bottles of beer.' || chr(10)
|
||||
|| 'Go to the store, buy some more!' || chr(10)
|
||||
|| '99 bottles of beer on the wall.',
|
||||
n || ' bottle' || if ( n = 1, '', 's') || ' of beer on the wall' || chr(10)
|
||||
|| n || ' bottle' || if ( n = 1, '', 's') || ' of beer;' || chr(10)
|
||||
|| 'Take one down, pass it around' || chr(10) ) )
|
||||
.array_to_string(chr(10)) ;
|
||||
21
Task/99-bottles-of-beer/DuckDB/99-bottles-of-beer-2.duckdb
Normal file
21
Task/99-bottles-of-beer/DuckDB/99-bottles-of-beer-2.duckdb
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
.header off
|
||||
.mode list
|
||||
|
||||
with recursive cte as (
|
||||
select 99 as n, '' as s
|
||||
union all
|
||||
select n-1 as n,
|
||||
if (n = 0,
|
||||
'No more bottles of beer on the wall' || chr(10)
|
||||
|| 'no more bottles of beer.' || chr(10)
|
||||
|| 'Go to the store, buy some more!' || chr(10)
|
||||
|| '99 bottles of beer on the wall.',
|
||||
n || ' bottle' || if ( n = 1, '', 's') || ' of beer on the wall' || chr(10)
|
||||
|| n || ' bottle' || if ( n = 1, '', 's') || ' of beer;' || chr(10)
|
||||
|| 'Take one down, pass it around' || chr(10) )
|
||||
from cte
|
||||
where n > -1
|
||||
) select s
|
||||
from cte
|
||||
where s != ''
|
||||
order by n desc ;
|
||||
12
Task/99-bottles-of-beer/Pluto/99-bottles-of-beer.pluto
Normal file
12
Task/99-bottles-of-beer/Pluto/99-bottles-of-beer.pluto
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
function pl(n) return n==1?"":"s" end
|
||||
|
||||
function fmt(s)
|
||||
return $"{s} bottle{pl(s)} of beer on the wall, \n" ..
|
||||
$"{s} bottle{pl(s)} of beer. \n" ..
|
||||
$"Take one down, pass it around, \n" ..
|
||||
$"{s-1} bottle{pl(s-1)} of beer on the wall.\n\n"
|
||||
end
|
||||
|
||||
for i = 99, 1, -1 do
|
||||
print(fmt(i))
|
||||
end
|
||||
13
Task/99-bottles-of-beer/Rhombus/99-bottles-of-beer.rhombus
Normal file
13
Task/99-bottles-of-beer/Rhombus/99-bottles-of-beer.rhombus
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#lang rhombus/static
|
||||
|
||||
for (i in 1..100):
|
||||
fun plural(n :: Int):
|
||||
if n == 1:
|
||||
| ""
|
||||
| "s"
|
||||
let bottles = 100 - i
|
||||
println(@str{@(bottles) bottle@(plural(bottles)) of beer on the wall, @(bottles) bottle@(plural(bottles)) of beer.})
|
||||
println(@str{Take one down and pass it around, @(bottles - 1) bottle@(plural(bottles - 1)) of beer on the wall.})
|
||||
|
||||
println("No more bottles of beer on the wall, no more bottles of beer.")
|
||||
println("Go to the store and buy some more, 99 bottles of beer on the wall.")
|
||||
|
|
@ -1,6 +1,10 @@
|
|||
scope
|
||||
local f := trim( io.read() ) split " "; # read a line and split into fields
|
||||
local a := tonumber( f[ 1 ] );
|
||||
local b := tonumber( f[ 2 ] );
|
||||
print( a + b )
|
||||
epocs
|
||||
try
|
||||
local a := tonumber( f[ 1 ] );
|
||||
local b := tonumber( f[ 2 ] );
|
||||
print( a + b )
|
||||
catch in ex then
|
||||
print( "Unable to add the numbers: ", tostring( ex ) )
|
||||
yrt
|
||||
end
|
||||
|
|
|
|||
9
Task/A+B/ArkScript/a+b.ark
Normal file
9
Task/A+B/ArkScript/a+b.ark
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
(import std.String :split)
|
||||
(import std.List :map :reduce)
|
||||
|
||||
(let in (input))
|
||||
(let numbers (map (split in " ") (fun (t) (toNumber t))))
|
||||
(print (reduce numbers (fun (a b)
|
||||
(if (nil? b)
|
||||
a
|
||||
(+ a b)))))
|
||||
5
Task/A+B/DuckDB/a+b-1.duckdb
Normal file
5
Task/A+B/DuckDB/a+b-1.duckdb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.headers off
|
||||
.mode list
|
||||
select sum(c::INTEGER)
|
||||
from (select unnest(regexp_extract_all(content, '[-0-9]+') ) as c
|
||||
from read_text('rc-a+b.txt') );
|
||||
2
Task/A+B/DuckDB/a+b-2.duckdb
Normal file
2
Task/A+B/DuckDB/a+b-2.duckdb
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
select a+b from (select column0 as a, column1 as b
|
||||
from read_csv('/dev/stdin', header=false, sep=' '));
|
||||
32
Task/A+B/Koka/a+b.koka
Normal file
32
Task/A+B/Koka/a+b.koka
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import std/os/readline
|
||||
|
||||
// A prompt effect which retries getting input until a valid result is returned.
|
||||
effect prompt
|
||||
ctl delimit(): () // Captures the retry resumption
|
||||
final ctl fail(): e // A failed input
|
||||
|
||||
// Prompt for input, with retry until successful result
|
||||
// - `message` is the original prompt
|
||||
// - `err-message` is the error shown on failure
|
||||
fun prompt(message: string, err-message: string, action: (string) -> <io,prompt|e> a): <io-noexn|e> a
|
||||
var reattempt := fn() impossible() // We ensure all paths include a delimiter
|
||||
with handler
|
||||
raw ctl delimit()
|
||||
reattempt := (fn() rcontext.resume(())) // set reattempt resumption
|
||||
reattempt() // Initial try
|
||||
final ctl fail()
|
||||
reattempt() // Handle failure by reattempting
|
||||
// Print the initial request message
|
||||
println(message)
|
||||
delimit() // Mark retry point
|
||||
try {
|
||||
action(readline()) // Read the input and apply the action
|
||||
} fn(err)
|
||||
// On an exception, print the error message and retry
|
||||
println(err-message)
|
||||
fail() // reset
|
||||
|
||||
fun main()
|
||||
with line <- prompt("Enter two numbers separated by space: ", "Invalid input, please enter two integers.")
|
||||
val [a, b] = line.split(" ")
|
||||
a.parse-int.unjust + b.parse-int.unjust
|
||||
2
Task/A+B/Pluto/a+b.pluto
Normal file
2
Task/A+B/Pluto/a+b.pluto
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
a, b = io.read("*n", "*n")
|
||||
print(a+b)
|
||||
6
Task/A+B/TAV/a+b.tav
Normal file
6
Task/A+B/TAV/a+b.tav
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
main(parms):+
|
||||
?# lne =: file () give lines \ void is standard input
|
||||
ab =: string lne split by many of #Whitespace
|
||||
a =: string ab[1] as integer
|
||||
b =: string ab[2] as integer
|
||||
print a + b
|
||||
45
Task/ABC-problem/DuckDB/abc-problem.duckdb
Normal file
45
Task/ABC-problem/DuckDB/abc-problem.duckdb
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
CREATE OR REPLACE FUNCTION matches(block, letter) as (
|
||||
block[1] = letter or block[2] = letter
|
||||
);
|
||||
|
||||
# permute(lst, n, word) generates sub-permutations, perm (of length n), of the list lst,
|
||||
# that satisfy matches(perm[i], word[i]), for i in range(1, n+1).
|
||||
# Normally n = length(word).
|
||||
# The caller is responsible for ensuring appropriate adjustment of typographical case.
|
||||
CREATE OR REPLACE FUNCTION permute(lst, n, word) as table (
|
||||
WITH RECURSIVE permute(perm, remaining) as (
|
||||
-- base case
|
||||
SELECT
|
||||
[]::VARCHAR[] as perm,
|
||||
lst::VARCHAR[] as remaining
|
||||
UNION ALL
|
||||
-- recursive case: add one element from remaining to perm and remove it from remaining
|
||||
SELECT
|
||||
(perm || [element]) AS perm,
|
||||
(remaining[1:i-1] || remaining[i+1:]) AS remaining
|
||||
FROM (select *, unnest(remaining) AS element, generate_subscripts(remaining,1) as i
|
||||
FROM permute)
|
||||
WHERE length(perm) < n
|
||||
and matches(element, word[1 + length(perm)])
|
||||
)
|
||||
SELECT perm
|
||||
FROM permute
|
||||
WHERE length(perm) = n
|
||||
);
|
||||
|
||||
# All solutions
|
||||
CREATE OR REPLACE FUNCTION solve(word) as table (
|
||||
from permute(
|
||||
['BO', 'XK', 'DQ', 'CP', 'NA', 'GT', 'RE', 'TG', 'QD', 'FS',
|
||||
'JW', 'HU', 'VI', 'AN', 'OB', 'ER', 'FS', 'LY', 'PC', 'ZM'],
|
||||
length(word), upper(word) )
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION one_solution(word) as (
|
||||
from solve(word)
|
||||
limit 1
|
||||
);
|
||||
|
||||
# Examples
|
||||
select word, one_solution(word)
|
||||
from (select unnest(['','A','BarK','BOOK','TREAT','COMMON','SQUAD','Confuse','abba']) as word);
|
||||
25
Task/ABC-problem/Pluto/abc-problem.pluto
Normal file
25
Task/ABC-problem/Pluto/abc-problem.pluto
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
function r(word, bl)
|
||||
if word == "" then return true end
|
||||
local c = word:byte(1) | 32
|
||||
for i = 1, #bl do
|
||||
local b = bl[i]
|
||||
if c == b:byte(1) | 32 or c == b:byte(2) | 32 then
|
||||
bl[i] = bl[1]
|
||||
bl[1] = b
|
||||
if r(word:sub(2), bl:slice(2)) then return true end
|
||||
bl[1], bl[i] = bl[i], bl[1]
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function new_speller(blocks)
|
||||
local bl = blocks:split(" ")
|
||||
return |word| -> r(word, bl)
|
||||
end
|
||||
|
||||
local sp = new_speller("BO XK DQ CP NA GT RE TG QD FS JW HU VI AN OB ER FS LY PC ZM")
|
||||
local words = {"A", "BARK", "BOOK", "TREAT", "COMMON", "SQUAD", "CONFUSE"}
|
||||
for words as word do
|
||||
print(string.format("%-7s %s", word, sp(word)))
|
||||
end
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
100 REM AKS test for primes
|
||||
110 DECLARE EXTERNAL SUB PascalTriangle
|
||||
120 DECLARE EXTERNAL SUB ExpandPoly
|
||||
130 DECLARE EXTERNAL FUNCTION IsPrime
|
||||
140 FOR N = 0 TO 9
|
||||
150 CALL ExpandPoly(N)
|
||||
160 NEXT N
|
||||
170 FOR N = 2 TO 50
|
||||
180 IF IsPrime(N) <> 0 THEN PRINT USING("###"): N;
|
||||
190 NEXT N
|
||||
200 PRINT
|
||||
210 END
|
||||
220 REM **
|
||||
230 EXTERNAL SUB PascalTriangle(N, PasTri())
|
||||
240 REM Calculate t!he N'th line 0.. middle
|
||||
250 LET N = INT(N)
|
||||
260 LET PasTri(0) = 1
|
||||
270 LET J = 1
|
||||
280 DO WHILE J <= N
|
||||
290 LET J = J + 1
|
||||
300 LET K = INT(J / 2)
|
||||
310 LET PasTri(K) = PasTri(K - 1)
|
||||
320 FOR K = K TO 1 STEP -1
|
||||
330 LET PasTri(K) = PasTri(K) + PasTri(K - 1)
|
||||
340 NEXT K
|
||||
350 LOOP
|
||||
360 END SUB
|
||||
370 REM **
|
||||
380 EXTERNAL FUNCTION IsPrime(N)
|
||||
390 LET N = INT(N)
|
||||
400 DIM PasTri(0 TO 50)
|
||||
410 LET PasTriMax = UBOUND(PasTri)
|
||||
420 IF N > PasTriMax THEN
|
||||
430 PRINT N; "is out of range"
|
||||
440 STOP
|
||||
450 END IF
|
||||
460 CALL PascalTriangle(N, PasTri)
|
||||
470 LET Res = 1
|
||||
480 LET I = INT(N / 2)
|
||||
490 DO WHILE (Res <> 0) AND (I > 1)
|
||||
500 IF (Res <> 0) AND (MOD(PasTri(I), N) = 0) THEN LET Res = 1 ELSE LET Res = 0
|
||||
510 LET I = I - 1
|
||||
520 LOOP
|
||||
530 LET IsPrime = Res
|
||||
540 END FUNCTION
|
||||
550 REM **
|
||||
560 EXTERNAL SUB ExpandPoly(N)
|
||||
570 LET N = INT(N)
|
||||
580 DIM VZ$(0 TO 1)
|
||||
590 LET VZ$(0) = "+"
|
||||
600 LET VZ$(1) = "-"
|
||||
610 DIM PasTri(0 TO 50)
|
||||
620 LET PasTriMax = UBOUND(PasTri)
|
||||
630 IF N > PasTriMax THEN
|
||||
640 PRINT N; "is out of range"
|
||||
650 STOP
|
||||
660 END IF
|
||||
670 SELECT CASE N
|
||||
680 CASE 0
|
||||
690 PRINT "(x - 1) ^ 0 = 1"
|
||||
700 CASE 1
|
||||
710 PRINT "(x - 1) ^ 1 = x - 1"
|
||||
720 CASE ELSE
|
||||
730 CALL PascalTriangle(N, PasTri)
|
||||
740 PRINT "(x - 1) ^"; N; " = x ^"; N;
|
||||
750 LET BVZ = 1
|
||||
760 FOR J = N - 1 TO INT(N / 2) + 1 STEP -1
|
||||
770 PRINT VZ$(BVZ); PasTri(N - J); "* x ^"; J;
|
||||
780 LET BVZ = ABS(1 - BVZ)
|
||||
790 NEXT J
|
||||
800 FOR J = INT(N / 2) TO 2 STEP -1
|
||||
810 PRINT VZ$(BVZ); PasTri(J); "* x ^"; J;
|
||||
820 LET BVZ = ABS(1 - BVZ)
|
||||
830 NEXT J
|
||||
840 PRINT VZ$(BVZ); PasTri(1); "* x ";
|
||||
850 LET BVZ = ABS(1 - BVZ)
|
||||
860 PRINT VZ$(BVZ); PasTri(0)
|
||||
870 END SELECT
|
||||
880 END SUB
|
||||
89
Task/AKS-test-for-primes/Agena/aks-test-for-primes.agena
Normal file
89
Task/AKS-test-for-primes/Agena/aks-test-for-primes.agena
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# AKS test for primes
|
||||
|
||||
constant pas_tri_max := 50;
|
||||
|
||||
proc pascal_triangle(n :: posint) is
|
||||
# Calculate the n'th line 1.. middle
|
||||
# For n = 1, 2, ..
|
||||
create register pas_tri((n + 1) \ 2);
|
||||
# pas_tri[0] always is 1
|
||||
j := 1;
|
||||
case n
|
||||
of 1, 2 then pas_tri[1] := 2
|
||||
else
|
||||
j := 3;
|
||||
pas_tri[1] := 2;
|
||||
while j <= n do
|
||||
j++;
|
||||
k := j \ 2; # middle
|
||||
pas_tri[k] := pas_tri[k - 1];
|
||||
while k >= 2 do
|
||||
pas_tri[k] +:= pas_tri[k - 1];
|
||||
k--
|
||||
od;
|
||||
pas_tri[1] +:= 1
|
||||
od
|
||||
esle
|
||||
esac
|
||||
return pas_tri
|
||||
end;
|
||||
|
||||
proc is_prime(n :: nonnegint) :: boolean is
|
||||
if n > pas_tri_max then
|
||||
printf("%d is out of range\n", n);
|
||||
os.exit(-1)
|
||||
fi;
|
||||
pas_tri := pascal_triangle(n);
|
||||
res := true;
|
||||
i := n \ 2;
|
||||
while res and (i > 1) do
|
||||
res := res and (pas_tri[i] symmod n = 0);
|
||||
i--
|
||||
od;
|
||||
return res
|
||||
end;
|
||||
|
||||
proc vz(b :: boolean) is
|
||||
return if b then '-' else '+' fi
|
||||
end;
|
||||
|
||||
proc expand_poly(n :: nonnegint) is
|
||||
if n > pas_tri_max then
|
||||
printf("%d is out of range\n", n);
|
||||
os.exit(-1)
|
||||
fi;
|
||||
case n
|
||||
of 0 then printf("(x-1)^0 = 1\n");
|
||||
of 1 then printf("(x-1)^1 = x-1\n");
|
||||
else
|
||||
pas_tri := pascal_triangle(n);
|
||||
printf("(x-1)^%d = x^%d", n, n);
|
||||
bvz := true;
|
||||
n_div_2 := n \ 2
|
||||
for j from n - 1 to n_div_2 + 1 by -1 do
|
||||
printf("%s%d*x^%d", vz(bvz), pas_tri[n - j], j);
|
||||
bvz := not bvz
|
||||
od;
|
||||
for j from n_div_2 to 2 by -1 do
|
||||
printf("%s%d*x^%d", vz(bvz), pas_tri[j], j);
|
||||
bvz := not bvz
|
||||
od;
|
||||
printf("%s%d*x", vz(bvz), pas_tri[1]);
|
||||
bvz := not bvz;
|
||||
printf("%s1\n", vz(bvz));
|
||||
esle
|
||||
esac
|
||||
end;
|
||||
|
||||
scope
|
||||
local n;
|
||||
for n from 0 to 9 do
|
||||
expand_poly(n)
|
||||
od;
|
||||
for n from 2 to pas_tri_max do
|
||||
if is_prime(n) then
|
||||
printf("%3d", n)
|
||||
fi
|
||||
od;
|
||||
printf("\n")
|
||||
end
|
||||
43
Task/AKS-test-for-primes/EasyLang/aks-test-for-primes.easy
Normal file
43
Task/AKS-test-for-primes/EasyLang/aks-test-for-primes.easy
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
func[] coefs n .
|
||||
list[] = [ 1 ]
|
||||
arrbase list[] 0
|
||||
for k = 0 to n : list[] &= list[k] * (n - k) / (k + 1)
|
||||
for k = 1 step 2 to n : list[k] = -list[k]
|
||||
return list[]
|
||||
.
|
||||
func isprimeaks n .
|
||||
c[] = coefs n
|
||||
c[0] -= 1
|
||||
c[n] += 1
|
||||
for i = 0 to n
|
||||
if c[i] mod n <> 0 : return 0
|
||||
.
|
||||
return 1
|
||||
.
|
||||
proc pprintcoefs n list[] .
|
||||
for i = 0 to n
|
||||
s$ = ""
|
||||
if i > 0
|
||||
s$ = " + "
|
||||
if list[i] < 0 : s$ = " - "
|
||||
.
|
||||
c$ = abs list[i]
|
||||
e = n - i
|
||||
if c$ = "1" and e > 0 : c$ = ""
|
||||
x$ = ""
|
||||
if e <> 0
|
||||
x$ = "x"
|
||||
if e <> 1 : x$ &= "^" & e
|
||||
.
|
||||
r$ &= s$ & c$ & x$
|
||||
.
|
||||
print "(x-1)^" & n & " : " & r$
|
||||
.
|
||||
for i = 0 to 7
|
||||
pprintcoefs i coefs i
|
||||
.
|
||||
print ""
|
||||
for i = 2 to 49
|
||||
if isprimeaks i = 1 : write i & " "
|
||||
.
|
||||
print ""
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
// AKS Test for Primes task
|
||||
// https://rosettacode.org/wiki/AKS_test_for_primes
|
||||
// Translated from Yabasic to FutureBASIC
|
||||
|
||||
|
||||
#build ShowMoreWarnings NO
|
||||
|
|
|
|||
119
Task/AKS-test-for-primes/Modula-2/aks-test-for-primes.mod2
Normal file
119
Task/AKS-test-for-primes/Modula-2/aks-test-for-primes.mod2
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
MODULE AKSTest;
|
||||
(* AKS test for primes *)
|
||||
|
||||
FROM STextIO IMPORT
|
||||
WriteLn, WriteString;
|
||||
FROM SWholeIO IMPORT
|
||||
WriteInt;
|
||||
|
||||
CONST
|
||||
PasTriMax = 33; (* for 32-bit integer type *)
|
||||
|
||||
TYPE
|
||||
TPasTri = ARRAY [0 .. PasTriMax] OF CARDINAL;
|
||||
|
||||
VAR
|
||||
N: CARDINAL;
|
||||
|
||||
PROCEDURE PascalTriangle(N: CARDINAL; VAR PasTri: TPasTri);
|
||||
(* Calculate the N'th line 0.. middle *)
|
||||
VAR
|
||||
J, K: CARDINAL;
|
||||
BEGIN
|
||||
PasTri[0] := 1;
|
||||
J := 1;
|
||||
WHILE J <= N DO
|
||||
J := J + 1;
|
||||
K := J DIV 2;
|
||||
PasTri[K] := PasTri[K - 1];
|
||||
FOR K := K TO 1 BY -1 DO
|
||||
PasTri[K] := PasTri[K] + PasTri[K - 1];
|
||||
END
|
||||
END
|
||||
END PascalTriangle;
|
||||
|
||||
PROCEDURE IsPrime(N: CARDINAL): BOOLEAN;
|
||||
VAR
|
||||
Res : BOOLEAN;
|
||||
I : CARDINAL;
|
||||
PasTri: TPasTri;
|
||||
BEGIN
|
||||
IF N > PasTriMax THEN
|
||||
WriteInt(N, 1);
|
||||
WriteString(" is out of range");
|
||||
WriteLn;
|
||||
HALT;
|
||||
END;
|
||||
PascalTriangle(N, PasTri);
|
||||
Res := TRUE;
|
||||
I := N DIV 2;
|
||||
WHILE Res AND (I > 1) DO
|
||||
Res := Res AND (PasTri[I] MOD N = 0);
|
||||
I := I - 1
|
||||
END;
|
||||
RETURN Res;
|
||||
END IsPrime;
|
||||
|
||||
PROCEDURE ExpandPoly(N: CARDINAL);
|
||||
TYPE
|
||||
TVZ = ARRAY BOOLEAN OF CHAR;
|
||||
CONST
|
||||
VZ = TVZ {'+', '-'};
|
||||
VAR
|
||||
J : CARDINAL;
|
||||
BVZ : BOOLEAN;
|
||||
PasTri: TPasTri;
|
||||
BEGIN
|
||||
IF N > PasTriMax THEN
|
||||
WriteInt(N, 1);
|
||||
WriteString(" is out of range");
|
||||
WriteLn;
|
||||
HALT
|
||||
END;
|
||||
CASE N OF
|
||||
| 0:
|
||||
WriteString("(x-1)^0 = 1"); WriteLn;
|
||||
| 1:
|
||||
WriteString("(x-1)^1 = x-1"); WriteLn;
|
||||
ELSE
|
||||
PascalTriangle(N, PasTri);
|
||||
WriteString("(x-1)^");
|
||||
WriteInt(N, 1);
|
||||
WriteString(" = x^");
|
||||
WriteInt(N, 1);
|
||||
BVZ := TRUE;
|
||||
FOR J := N - 1 TO N DIV 2 + 1 BY -1 DO
|
||||
WriteString(VZ[BVZ]);
|
||||
WriteInt(PasTri[N - J], 1);
|
||||
WriteString("*x^");
|
||||
WriteInt(J, 1);
|
||||
BVZ := NOT BVZ
|
||||
END;
|
||||
FOR J := N DIV 2 TO 2 BY -1 DO
|
||||
WriteString(VZ[BVZ]);
|
||||
WriteInt(PasTri[J], 1);
|
||||
WriteString("*x^");
|
||||
WriteInt(J, 1);
|
||||
BVZ := NOT BVZ
|
||||
END;
|
||||
WriteString(VZ[BVZ]);
|
||||
WriteInt(PasTri[1], 1);
|
||||
WriteString("*x");
|
||||
BVZ := NOT BVZ;
|
||||
WriteString(VZ[BVZ]);
|
||||
WriteInt(PasTri[0], 1);
|
||||
WriteLn;
|
||||
END;
|
||||
END ExpandPoly;
|
||||
|
||||
BEGIN
|
||||
FOR N := 0 TO 9 DO
|
||||
ExpandPoly(N)
|
||||
END;
|
||||
FOR N := 2 TO PasTriMax DO
|
||||
IF IsPrime(N) THEN
|
||||
WriteInt(N, 3)
|
||||
END
|
||||
END;
|
||||
WriteLn;
|
||||
END AKSTest.
|
||||
80
Task/AKS-test-for-primes/PHP/aks-test-for-primes.php
Normal file
80
Task/AKS-test-for-primes/PHP/aks-test-for-primes.php
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
// AKS test for primes
|
||||
|
||||
const PAS_TRI_MAX = 61;
|
||||
|
||||
function vz($b) {
|
||||
return ($b ? "-" : "+");
|
||||
}
|
||||
|
||||
function expand_poly($n) {
|
||||
if ($n > PAS_TRI_MAX) {
|
||||
echo $n, " is out of range", PHP_EOL;
|
||||
exit;
|
||||
}
|
||||
switch ($n) {
|
||||
case 0:
|
||||
echo "(x-1)^0 = 1", PHP_EOL;
|
||||
break;
|
||||
case 1:
|
||||
echo "(x-1)^1 = x-1", PHP_EOL;
|
||||
break;
|
||||
default:
|
||||
$pas_tri = [];
|
||||
pascal_triangle($n, $pas_tri);
|
||||
echo "(x-1)^", $n, " = x^", $n;
|
||||
$bvz = true;
|
||||
$n_div_2 = intdiv($n, 2);
|
||||
for ($j = $n - 1; $j > $n_div_2; $j--) {
|
||||
echo vz($bvz), $pas_tri[$n - $j], "*x^", $j;
|
||||
$bvz = !$bvz;
|
||||
}
|
||||
for ($j = $n_div_2; $j >= 2; $j--) {
|
||||
echo vz($bvz), $pas_tri[$j], "*x^", $j;
|
||||
$bvz = !$bvz;
|
||||
}
|
||||
echo vz($bvz), $pas_tri[1], "*x";
|
||||
$bvz = !$bvz;
|
||||
echo vz($bvz), $pas_tri[0], PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
function pascal_triangle($n, &$pas_tri) {
|
||||
// Calculate the $n'th line 0.. middle
|
||||
$pas_tri = array_fill(0, intdiv($n + 1, 2) + 1, 0);
|
||||
$pas_tri[0] = 1;
|
||||
$j = 1;
|
||||
while ($j <= $n) {
|
||||
$j++;
|
||||
$k = intdiv($j, 2);
|
||||
$pas_tri[$k] = $pas_tri[$k - 1];
|
||||
while ($k >= 1) {
|
||||
$pas_tri[$k] += $pas_tri[$k - 1];
|
||||
$k--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function is_prime($n):bool {
|
||||
if ($n > PAS_TRI_MAX) {
|
||||
echo $n, " is out of range", PHP_EOL;
|
||||
exit;
|
||||
}
|
||||
$pas_tri = [];
|
||||
pascal_triangle($n, $pas_tri);
|
||||
$res = true;
|
||||
$i = intdiv($n, 2);
|
||||
while ($res && ($i > 1)) {
|
||||
$res = $res && ($pas_tri[$i] % $n == 0);
|
||||
--$i;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
for ($n = 0; $n <= 9; $n++)
|
||||
expand_poly($n);
|
||||
for ($n = 2; $n <= PAS_TRI_MAX; $n++)
|
||||
if (is_prime($n))
|
||||
echo str_pad($n, 3, " ", STR_PAD_LEFT);
|
||||
echo PHP_EOL;
|
||||
?>
|
||||
90
Task/AKS-test-for-primes/Pluto/aks-test-for-primes.pluto
Normal file
90
Task/AKS-test-for-primes/Pluto/aks-test-for-primes.pluto
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
do -- "AKS test for promes" task - translated from the Algol 68 sample
|
||||
|
||||
local bigint = require "pluto:bigint"
|
||||
local b0, b1 = new bigint( 0 ), new bigint( 1 )
|
||||
--[[
|
||||
Mathematical preliminaries.
|
||||
|
||||
First note that the homogeneous polynomial (a+b)^n is symmetrical
|
||||
(to see this just swap the variables a and b). Therefore its
|
||||
coefficients need be calculated only to that of (ab)^{n/2} for even
|
||||
n or (ab)^{(n-1)/2} for odd n.
|
||||
|
||||
Second, the coefficients are the binomial coefficients C(n,k) where
|
||||
the coefficient of a^k b^(n-k) is C(n,k) = n! / k! (k-1)!. This
|
||||
leads to an immediate and relatively efficient implementation for
|
||||
which we do not need to compute n! before dividing by k! and (k-1)!
|
||||
but, rather cancel common factors as we go along. Further, the
|
||||
well-known symmetry identity C(n,k) = C(n, n-k) allows a
|
||||
significant reduction in computational effort.
|
||||
|
||||
Third, (x-1)^n is the value of (a + b)^n when a=x and b = -1. The
|
||||
powers of -1 alternate between +1 and -1 so we may as well compute
|
||||
(x+1)^n and negate every other coefficient when printing.
|
||||
]]
|
||||
|
||||
local function choose( n, k )
|
||||
local result = b1
|
||||
local symK = if k >= n//2 then n-k else k end -- Use symmetry
|
||||
if symK > 0 then
|
||||
local iPlus1 = b1
|
||||
local nMinusI = new bigint( n )
|
||||
for _ = 0, symK-1 do
|
||||
result *= nMinusI
|
||||
result /= iPlus1
|
||||
iPlus1 += b1
|
||||
nMinusI -= b1
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
local function coefficients( n )
|
||||
local a = {}
|
||||
for i = 0, n//2 do
|
||||
a[i] = choose( n, i )
|
||||
a[n-i] = a[i] -- Use symmetry
|
||||
end
|
||||
return a
|
||||
end
|
||||
--[[
|
||||
First print the polynomials (x-1)^n, remembering to alternate signs
|
||||
and to tidy up the constant term, the x^1 term and the x^n term.
|
||||
This means we must treat (x-1)^0 and (x-1)^1 specially
|
||||
]]
|
||||
for n = 0,7 do
|
||||
local a = coefficients( n )
|
||||
io.write( "(x-1)^"..n.." = " )
|
||||
switch n do
|
||||
case 0: io.write( tostring( a[0] ) ) break
|
||||
case 1: io.write( "x - "..tostring( a[1] ) ) break
|
||||
default: io.write( "x^"..n )
|
||||
for i = 1,n-2 do
|
||||
local ai = tostring( a[i] )
|
||||
io.write( if i % 2 == 1 then " - " else " + " end..ai.."x^"..(n-i) )
|
||||
end
|
||||
io.write( if ( n - 1 ) % 2 == 1 then " - " else " + " end..tostring( a[n-1] ).."x" )
|
||||
io.write( if n % 2 == 1 then " - " else " + " end..tostring( a[n] ) )
|
||||
end
|
||||
io.write( "\n" )
|
||||
end
|
||||
--[[
|
||||
Finally, for the "AKS" portion of the task, the sign of the
|
||||
coefficient has no effect on its divisibility by p so, once again,
|
||||
we may as well use the positive coefficients. Symmetry clearly
|
||||
reduces the necessary number of tests by a factor of two.
|
||||
]]
|
||||
local function isPrime( n )
|
||||
local prime = true
|
||||
local bn = new bigint( n )
|
||||
for i = 1,n//2 do
|
||||
prime = choose( n, i ) % bn == b0
|
||||
if not prime then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
io.write( "Primes between 1 and 50 are:" )
|
||||
for n = 2,50 do if isPrime(n) then io.write( " "..n ) end end
|
||||
io.write( "\nPrimes between 900 and 1000 are:")
|
||||
for n = 900,1000 do if isPrime(n) then io.write( " "..n ) end end
|
||||
io.write( "\n" )
|
||||
end
|
||||
84
Task/AKS-test-for-primes/PowerShell/aks-test-for-primes.psh
Normal file
84
Task/AKS-test-for-primes/PowerShell/aks-test-for-primes.psh
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
# AKS test for primes
|
||||
|
||||
$script:PasTriMax = 61 # for long type of Pascal triangle numbers
|
||||
|
||||
function Pascal-Triangle {
|
||||
# Calculate the n'th line 0.. middle
|
||||
param(
|
||||
[int]$N
|
||||
)
|
||||
|
||||
$pasTri = [long[]]::new([math]::Ceiling(($N + 2) / 2))
|
||||
$pasTri[0] = 1
|
||||
[int]$j = 1
|
||||
while ($j -le $N) {
|
||||
$j++
|
||||
[int]$k = [math]::Floor($j / 2)
|
||||
$pasTri[$k] = $pasTri[$k - 1]
|
||||
for (; $k -ge 1; $k--) {
|
||||
$pasTri[$k] += $pasTri[$k - 1]
|
||||
}
|
||||
}
|
||||
# Now: $j -eq ($N + 1), so $k -eq [math]::Floor(($N + 1) / 2)
|
||||
return $pasTri
|
||||
}
|
||||
|
||||
function Expand-Poly {
|
||||
param ([int]$N)
|
||||
|
||||
if ($N -gt $script:PasTriMax) {
|
||||
throw "$N is out of range"
|
||||
}
|
||||
switch($N) {
|
||||
0 {Write-Output "(x-1)^0 = 1"}
|
||||
1 {Write-Output "(x-1)^1 = x-1"}
|
||||
default {
|
||||
$VZ = @('+', '-')
|
||||
$pasTri = Pascal-Triangle($N)
|
||||
[string]$outTri = @()
|
||||
$outTri += "(x-1)^$N = x^$N"
|
||||
[bool]$bVz = $true
|
||||
[int]$nDiv2 = [math]::Floor($N / 2)
|
||||
for ([int]$j = $N - 1; $j -gt $nDiv2; $j--) {
|
||||
$outTri += "$($VZ[$bVz]) $($pasTri[$N - $j])*x^$j"
|
||||
$bVz = -not $bVz
|
||||
}
|
||||
for ([int]$j = $nDiv2; $j -gt 1; $j--) {
|
||||
$outTri += "$($VZ[$bVz]) $($pasTri[$j])*x^$j"
|
||||
$bVz = -not $bVz
|
||||
}
|
||||
$outTri += "$($VZ[$bVz]) $($pasTri[1])*x"
|
||||
$bVz = -not $bVz
|
||||
$outTri += "$($VZ[$bVz]) $($pasTri[0])"
|
||||
Write-Output $outTri
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Is-Prime {
|
||||
param([int]$N)
|
||||
|
||||
if ($N -gt $script:PasTriMax) {
|
||||
throw "$N is out of range"
|
||||
}
|
||||
$pasTri = Pascal-Triangle($N)
|
||||
[bool]$res = $true
|
||||
[int]$i = [math]::Floor($N / 2)
|
||||
while ($res -and ($i -gt 1)) {
|
||||
$res = $res -and ($pasTri[$i] % $N -eq 0)
|
||||
$i--
|
||||
}
|
||||
return $res
|
||||
}
|
||||
|
||||
# Test program
|
||||
foreach ($n in 0..9) {
|
||||
Expand-Poly($n)
|
||||
}
|
||||
[string]$primes = @()
|
||||
foreach ($n in 2..$script:PasTriMax) {
|
||||
if (Is-Prime($n)) {
|
||||
$primes += "{0,3}" -f $n
|
||||
}
|
||||
}
|
||||
Write-Output $primes
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
-- 22 Mar 2025
|
||||
-- 28 Jul 2025
|
||||
include Settings
|
||||
arg p
|
||||
if p = '' then
|
||||
p = 10
|
||||
|
||||
say 'AKS TEST FOR PRIMES'
|
||||
say version
|
||||
say
|
||||
arg p
|
||||
if p = '' then
|
||||
p = 10
|
||||
numeric digits Max(10,Abs(p)%3)
|
||||
call Combis p
|
||||
call Polynomials p
|
||||
|
|
@ -37,9 +37,9 @@ else
|
|||
b = 0
|
||||
p = Abs(p); prim. = 0; n = 0
|
||||
do i = b to p
|
||||
a = Ppow('1 -1',i)
|
||||
a = PowP('1 -1',i)
|
||||
if i < 11 then
|
||||
say '(x-1)^'i '=' Plst2form(Parr2lst())
|
||||
say '(x-1)^'i '=' Lst2FormP(Arr2LstP())
|
||||
s = 1
|
||||
do j = 2 to poly.0-1
|
||||
a = poly.coef.j
|
||||
|
|
@ -84,8 +84,4 @@ say Format(Time('e'),,3) 'seconds'
|
|||
say
|
||||
return
|
||||
|
||||
include Functions
|
||||
include Numbers
|
||||
include Polynomial
|
||||
include Sequences
|
||||
include Abend
|
||||
include Math
|
||||
|
|
|
|||
84
Task/AKS-test-for-primes/XBasic/aks-test-for-primes.basic
Normal file
84
Task/AKS-test-for-primes/XBasic/aks-test-for-primes.basic
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
PROGRAM "akstest"
|
||||
' AKS test for primes
|
||||
|
||||
DECLARE FUNCTION Entry ()
|
||||
INTERNAL FUNCTION ExpandPoly(n@@)
|
||||
INTERNAL FUNCTION PascalTriangle(n@@, @pasTri&&[])
|
||||
INTERNAL FUNCTION IsPrime(n@@)
|
||||
INTERNAL FUNCTION Vz$(b@)
|
||||
$$PasTriMax = 33 ' for 32-bit integer type
|
||||
|
||||
FUNCTION Entry()
|
||||
FOR n@@ = 0 TO 9
|
||||
ExpandPoly(n@@)
|
||||
NEXT
|
||||
FOR n@@ = 2 TO $$PasTriMax
|
||||
IF IsPrime(n@@) THEN PRINT FORMAT$("###", n@@);
|
||||
NEXT
|
||||
PRINT
|
||||
END FUNCTION
|
||||
|
||||
FUNCTION ExpandPoly(n@@)
|
||||
DIM pasTri&&[$$PasTriMax]
|
||||
IF n@@ > $$PasTriMax THEN
|
||||
PRINT n@@; " is out of range"
|
||||
QUIT(1)
|
||||
END IF
|
||||
SELECT CASE n@@
|
||||
CASE 0:
|
||||
PRINT "(x - 1) ^ 0 = 1"
|
||||
CASE 1:
|
||||
PRINT "(x - 1) ^ 1 = x - 1"
|
||||
CASE ELSE:
|
||||
PascalTriangle(n@@, @pasTri&&[])
|
||||
PRINT "(x - 1) ^"; n@@; " = x ^"; n@@;
|
||||
bVz@ = $$TRUE
|
||||
FOR j@@ = n@@ - 1 TO n@@ \ 2 + 1 STEP -1
|
||||
PRINT " "; Vz$(bVz@); pasTri&&[n@@ - j@@]; " * x ^"; j@@;
|
||||
bVz@ = NOT bVz@
|
||||
NEXT
|
||||
FOR j@@ = n@@ \ 2 TO 2 STEP -1
|
||||
PRINT " "; Vz$(bVz@); pasTri&&[j@@]; " * x ^"; j@@;
|
||||
bVz@ = NOT bVz@
|
||||
NEXT
|
||||
PRINT " "; Vz$(bVz@); pasTri&&[1]; " * x ";
|
||||
bVz@ = NOT bVz@
|
||||
PRINT Vz$(bVz@); pasTri&&[0]
|
||||
END SELECT
|
||||
|
||||
END FUNCTION
|
||||
|
||||
FUNCTION PascalTriangle(n@@, @pasTri&&[])
|
||||
' Calculate the n@@'th line 0.. middle
|
||||
pasTri&&[0] = 1
|
||||
j@@ = 1
|
||||
DO WHILE j@@ <= n@@
|
||||
INC j@@
|
||||
k@@ = j@@ \ 2
|
||||
pasTri&&[k@@] = pasTri&&[k@@ - 1]
|
||||
FOR k@@ = k@@ TO 1 STEP -1
|
||||
pasTri&&[k@@] = pasTri&&[k@@] + pasTri&&[k@@ - 1]
|
||||
NEXT
|
||||
LOOP
|
||||
END FUNCTION
|
||||
|
||||
FUNCTION IsPrime(n@@)
|
||||
DIM pasTri&&[$$PasTriMax]
|
||||
IF n@@ > $$PasTriMax THEN
|
||||
PRINT n@@; " is out of range"
|
||||
QUIT(1)
|
||||
END IF
|
||||
PascalTriangle(n@@, @pasTri&&[])
|
||||
res@ = $$TRUE
|
||||
i@@ = n@@ \ 2
|
||||
DO WHILE res@ AND (i@@ > 1)
|
||||
res@ = res@ AND (pasTri&&[i@@] MOD n@@ = 0)
|
||||
DEC i@@
|
||||
LOOP
|
||||
RETURN res@
|
||||
END FUNCTION
|
||||
|
||||
FUNCTION Vz$(b@)
|
||||
IF b@ THEN RETURN "-" ELSE RETURN "+"
|
||||
END FUNCTION
|
||||
END PROGRAM
|
||||
105
Task/AKS-test-for-primes/XPL0/aks-test-for-primes.xpl0
Normal file
105
Task/AKS-test-for-primes/XPL0/aks-test-for-primes.xpl0
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
\AKS test for primes
|
||||
code Rem=2, ChOut=8, CrLf=9, Text=12, IntOut=11;
|
||||
code real RlOut=48, Float=49, Format=52;
|
||||
define PasTriMax = 33; \for 32-bit integer type
|
||||
integer N;
|
||||
|
||||
procedure PascalTriangle(N, PasTri);
|
||||
\Calculate the N'th line 0.. middle
|
||||
integer N, PasTri;
|
||||
integer J, K;
|
||||
begin
|
||||
PasTri(0):= 1;
|
||||
J:= 1;
|
||||
while J <= N do
|
||||
begin
|
||||
J:= J + 1;
|
||||
K:= J / 2;
|
||||
PasTri(K):= PasTri(K - 1);
|
||||
for K:= K downto 1 do PasTri(K):= PasTri(K) + PasTri(K - 1)
|
||||
end \while
|
||||
end;
|
||||
|
||||
function integer IsPrime(N);
|
||||
integer N;
|
||||
integer Res, I, PasTri(PasTriMax + 1);
|
||||
begin
|
||||
if N > PasTriMax then
|
||||
begin
|
||||
IntOut(0, N);
|
||||
Text(0, " is out of range");
|
||||
CrLf(0);
|
||||
exit;
|
||||
end;
|
||||
PascalTriangle(N, PasTri);
|
||||
Res:= true;
|
||||
I:= N / 2;
|
||||
while Res & (I > 1) do
|
||||
begin
|
||||
Res:= Res & (Rem(PasTri(I) / N) = 0);
|
||||
I:= I - 1
|
||||
end;
|
||||
return Res;
|
||||
end;
|
||||
|
||||
procedure ExpandPoly(N);
|
||||
integer N;
|
||||
integer J, BVZ, PasTri(PasTriMax + 1);
|
||||
|
||||
procedure VZOut(D, B);
|
||||
integer D, B;
|
||||
begin
|
||||
if B then ChOut(D, ^-) else ChOut(D, ^+)
|
||||
end;
|
||||
|
||||
begin
|
||||
if N > PasTriMax then
|
||||
begin
|
||||
IntOut(0, N);
|
||||
Text(0, " is out of range");
|
||||
CrLf(0);
|
||||
exit
|
||||
end;
|
||||
case N of
|
||||
0: [Text(0, "(x-1)^^0 = 1"); CrLf(0)];
|
||||
1: [Text(0, "(x-1)^^1 = x-1"); CrLf(0)]
|
||||
other
|
||||
begin
|
||||
PascalTriangle(N, PasTri);
|
||||
Text(0, "(x-1)^^");
|
||||
IntOut(0, N);
|
||||
Text(0, " = x^^");
|
||||
IntOut(0, N);
|
||||
BVZ:= true;
|
||||
for J:= N - 1 downto N / 2 + 1 do
|
||||
begin
|
||||
VZOut(0, BVZ);
|
||||
IntOut(0, PasTri(N - J));
|
||||
Text(0, "*x^^");
|
||||
IntOut(0, J);
|
||||
BVZ:= ~BVZ;
|
||||
end;
|
||||
for J:= N / 2 downto 2 do
|
||||
begin
|
||||
VZOut(0, BVZ);
|
||||
IntOut(0, PasTri(J));
|
||||
Text(0, "*x^^");
|
||||
IntOut(0, J);
|
||||
BVZ:= ~BVZ
|
||||
end;
|
||||
VZOut(0, BVZ);
|
||||
IntOut(0, PasTri(1));
|
||||
Text(0, "*x");
|
||||
BVZ:= ~BVZ;
|
||||
VZOut(0, BVZ);
|
||||
IntOut(0, PasTri(0));
|
||||
CrLf(0);
|
||||
end \case other
|
||||
end;
|
||||
|
||||
begin
|
||||
for N:= 0 to 9 do ExpandPoly(N);
|
||||
for N:= 2 to PasTriMax do
|
||||
if IsPrime(N) then [Format(3,0); RlOut(0, Float(N))];
|
||||
CrLf(0);
|
||||
end
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
diagram = "
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| ID |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| QDCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| ANCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| NSCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| ARCOUNT |
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+";
|
||||
|
||||
testhexdata = "78477bbf5496e12e1bf169a4";
|
||||
|
||||
(* Define BitField as an Association instead of a struct *)
|
||||
createBitField[name_, bits_, fieldstart_, fieldend_] :=
|
||||
<|"name" -> name, "bits" -> bits, "fieldstart" -> fieldstart, "fieldend" -> fieldend|>;
|
||||
|
||||
diagramToStruct[txt_] := Module[{bitfields = {}, lines, nbits, fieldpos, bitaccum,
|
||||
bitsize, bitlabel, bitstart, bitend},
|
||||
lines = StringTrim /@ StringSplit[txt, "\n"];
|
||||
|
||||
Do[
|
||||
nbits = StringCount[lines[[row]], "+"] - 1;
|
||||
fieldpos = StringPosition[lines[[row + 1]], "|"][[All, 1]];
|
||||
bitaccum = Floor[row/2] * nbits;
|
||||
|
||||
Do[
|
||||
endfield = fieldpos[[i + 1]];
|
||||
bitsize = Floor[(endfield - field)/3];
|
||||
bitlabel = StringTrim[StringTake[lines[[row + 1]], {field + 1, endfield - 1}]];
|
||||
bitstart = Floor[(field - 1)/3] + bitaccum;
|
||||
bitend = bitstart + bitsize - 1;
|
||||
AppendTo[bitfields, createBitField[bitlabel, bitsize, bitstart, bitend]],
|
||||
|
||||
{i, 1, Length[fieldpos] - 1}, {field, {fieldpos[[i]]}}
|
||||
],
|
||||
|
||||
{row, 1, Length[lines] - 1, 2}
|
||||
];
|
||||
|
||||
bitfields
|
||||
];
|
||||
|
||||
(* Convert a hex byte to binary string with padding *)
|
||||
binByte[c_] := IntegerString[FromDigits[c, 16], 2, 8];
|
||||
|
||||
(* Convert entire hex string to binary *)
|
||||
hexToBinary[s_] := StringJoin[
|
||||
binByte /@ (StringTake[s, {#, # + 1}] & /@ Range[1, StringLength[s] - 1, 2])
|
||||
];
|
||||
|
||||
validator[binstring_, fields_] :=
|
||||
StringLength[binstring] == Total[#["bits"] & /@ fields];
|
||||
|
||||
bitReader[bitfields_, hexdata_] := Module[{b, pat},
|
||||
Print["\nEvaluation of hex data ", hexdata, " as bitfields:"];
|
||||
Print["Name Size Bits\n------- ---- ----------------"];
|
||||
|
||||
b = hexToBinary[hexdata];
|
||||
Assert[validator[b, bitfields]];
|
||||
|
||||
Do[
|
||||
pat = StringTake[b, {bf["fieldstart"] + 1, bf["fieldend"] + 1}];
|
||||
Print[StringPadRight[bf["name"], 9],
|
||||
StringPadRight[ToString[bf["bits"]], 6],
|
||||
StringPadLeft[pat, 16]],
|
||||
{bf, bitfields}
|
||||
]
|
||||
];
|
||||
|
||||
decoded = diagramToStruct[diagram];
|
||||
|
||||
Print["Diagram as bit fields:\nName Bits Start End\n------ ---- ----- ---"];
|
||||
Do[
|
||||
Print[StringPadRight[bf["name"], 8],
|
||||
StringPadRight[ToString[bf["bits"]], 6],
|
||||
StringPadRight[ToString[bf["fieldstart"]], 6],
|
||||
StringPadLeft[ToString[bf["fieldend"]], 4]],
|
||||
{bf, decoded}
|
||||
];
|
||||
|
||||
bitReader[decoded, testhexdata];
|
||||
221
Task/AVL-tree/Dart/avl-tree.dart
Normal file
221
Task/AVL-tree/Dart/avl-tree.dart
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
class Node {
|
||||
int key;
|
||||
int balance = 0;
|
||||
int height = 0;
|
||||
Node? left;
|
||||
Node? right;
|
||||
Node? parent;
|
||||
|
||||
Node(this.key, this.parent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class AVLTree {
|
||||
Node? root;
|
||||
|
||||
bool insert(int key) {
|
||||
if (root == null) {
|
||||
root = Node(key, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
Node? n = root;
|
||||
while (true) {
|
||||
if (n!.key == key) return false;
|
||||
|
||||
Node parent = n;
|
||||
|
||||
bool goLeft = n.key > key;
|
||||
n = goLeft ? n.left : n.right;
|
||||
|
||||
if (n == null) {
|
||||
if (goLeft) {
|
||||
parent.left = Node(key, parent);
|
||||
} else {
|
||||
parent.right = Node(key, parent);
|
||||
}
|
||||
rebalance(parent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void _delete(Node node) {
|
||||
if (node.left == null && node.right == null) {
|
||||
if (node.parent == null) {
|
||||
root = null;
|
||||
} else {
|
||||
Node parent = node.parent!;
|
||||
if (parent.left == node) {
|
||||
parent.left = null;
|
||||
} else {
|
||||
parent.right = null;
|
||||
}
|
||||
rebalance(parent);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.left != null) {
|
||||
Node child = node.left!;
|
||||
while (child.right != null) child = child.right!;
|
||||
node.key = child.key;
|
||||
_delete(child);
|
||||
} else {
|
||||
Node child = node.right!;
|
||||
while (child.left != null) child = child.left!;
|
||||
node.key = child.key;
|
||||
_delete(child);
|
||||
}
|
||||
}
|
||||
|
||||
void delete(int delKey) {
|
||||
if (root == null) return;
|
||||
|
||||
Node? child = root;
|
||||
while (child != null) {
|
||||
Node node = child;
|
||||
child = delKey >= node.key ? node.right : node.left;
|
||||
if (delKey == node.key) {
|
||||
_delete(node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rebalance(Node n) {
|
||||
setBalance(n);
|
||||
|
||||
if (n.balance == -2) {
|
||||
if (height(n.left!.left) >= height(n.left!.right)) {
|
||||
n = rotateRight(n);
|
||||
} else {
|
||||
n = rotateLeftThenRight(n);
|
||||
}
|
||||
} else if (n.balance == 2) {
|
||||
if (height(n.right!.right) >= height(n.right!.left)) {
|
||||
n = rotateLeft(n);
|
||||
} else {
|
||||
n = rotateRightThenLeft(n);
|
||||
}
|
||||
}
|
||||
|
||||
if (n.parent != null) {
|
||||
rebalance(n.parent!);
|
||||
} else {
|
||||
root = n;
|
||||
}
|
||||
}
|
||||
|
||||
Node rotateLeft(Node a) {
|
||||
Node b = a.right!;
|
||||
b.parent = a.parent;
|
||||
|
||||
a.right = b.left;
|
||||
|
||||
if (a.right != null) a.right!.parent = a;
|
||||
|
||||
b.left = a;
|
||||
a.parent = b;
|
||||
|
||||
if (b.parent != null) {
|
||||
if (b.parent!.right == a) {
|
||||
b.parent!.right = b;
|
||||
} else {
|
||||
b.parent!.left = b;
|
||||
}
|
||||
}
|
||||
|
||||
setBalance(a, b);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
Node rotateRight(Node a) {
|
||||
Node b = a.left!;
|
||||
b.parent = a.parent;
|
||||
|
||||
a.left = b.right;
|
||||
|
||||
if (a.left != null) a.left!.parent = a;
|
||||
|
||||
b.right = a;
|
||||
a.parent = b;
|
||||
|
||||
if (b.parent != null) {
|
||||
if (b.parent!.right == a) {
|
||||
b.parent!.right = b;
|
||||
} else {
|
||||
b.parent!.left = b;
|
||||
}
|
||||
}
|
||||
|
||||
setBalance(a, b);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
Node rotateLeftThenRight(Node n) {
|
||||
n.left = rotateLeft(n.left!);
|
||||
return rotateRight(n);
|
||||
}
|
||||
|
||||
Node rotateRightThenLeft(Node n) {
|
||||
n.right = rotateRight(n.right!);
|
||||
return rotateLeft(n);
|
||||
}
|
||||
|
||||
int height(Node? n) {
|
||||
if (n == null) return -1;
|
||||
return n.height;
|
||||
}
|
||||
|
||||
void setBalance(Node n, [Node? n2]) {
|
||||
reheight(n);
|
||||
n.balance = height(n.right) - height(n.left);
|
||||
|
||||
if (n2 != null) {
|
||||
reheight(n2);
|
||||
n2.balance = height(n2.right) - height(n2.left);
|
||||
}
|
||||
}
|
||||
|
||||
void printBalance() {
|
||||
_printBalance(root);
|
||||
}
|
||||
|
||||
void _printBalance(Node? n) {
|
||||
if (n != null) {
|
||||
_printBalance(n.left);
|
||||
print('${n.balance} ');
|
||||
_printBalance(n.right);
|
||||
}
|
||||
}
|
||||
|
||||
void reheight(Node node) {
|
||||
if (node != null) {
|
||||
node.height = 1 + (height(node.left) > height(node.right)
|
||||
? height(node.left)
|
||||
: height(node.right));
|
||||
}
|
||||
}
|
||||
|
||||
static void main() {
|
||||
AVLTree tree = AVLTree();
|
||||
|
||||
print('Inserting values 1 to 10');
|
||||
for (int i = 1; i < 10; i++) {
|
||||
tree.insert(i);
|
||||
}
|
||||
|
||||
print('Printing balance: ');
|
||||
tree.printBalance();
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
AVLTree.main();
|
||||
}
|
||||
243
Task/AVL-tree/Swift/avl-tree.swift
Normal file
243
Task/AVL-tree/Swift/avl-tree.swift
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
import Foundation
|
||||
|
||||
// MARK: - AVL Tree ---------------------------------------------------------
|
||||
|
||||
final class AVLTree {
|
||||
// ---------- Node ------------------------------------------------------
|
||||
private class Node {
|
||||
var key: Int
|
||||
var balance: Int = 0
|
||||
var height: Int = 0
|
||||
|
||||
var left: Node?
|
||||
var right: Node?
|
||||
weak var parent: Node? // weak to avoid retain cycles
|
||||
|
||||
init(key: Int, parent: Node?) {
|
||||
self.key = key
|
||||
self.parent = parent
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Root -------------------------------------------------------
|
||||
private var root: Node?
|
||||
|
||||
// ---------- Public API -------------------------------------------------
|
||||
|
||||
/// Inserts `key`. Returns `true` if the key was added, `false` if it already existed.
|
||||
@discardableResult
|
||||
func insert(_ key: Int) -> Bool {
|
||||
// empty tree → new root
|
||||
guard let rootNode = root else {
|
||||
root = Node(key: key, parent: nil)
|
||||
return true
|
||||
}
|
||||
|
||||
var n: Node? = rootNode
|
||||
while let cur = n {
|
||||
if cur.key == key { return false } // duplicate
|
||||
|
||||
let goLeft = key < cur.key
|
||||
let parent = cur
|
||||
n = goLeft ? cur.left : cur.right
|
||||
|
||||
// we have found the empty spot → insert
|
||||
if n == nil {
|
||||
let newNode = Node(key: key, parent: parent)
|
||||
if goLeft {
|
||||
parent.left = newNode
|
||||
} else {
|
||||
parent.right = newNode
|
||||
}
|
||||
rebalance(parent) // fix AVL balance upwards
|
||||
break
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/// Deletes `key` if it exists. Does nothing when the key is not present.
|
||||
func delete(_ key: Int) {
|
||||
var current = root
|
||||
while let node = current {
|
||||
if key == node.key {
|
||||
delete(node) // internal helper that really removes the node
|
||||
return
|
||||
}
|
||||
current = (key < node.key) ? node.left : node.right
|
||||
}
|
||||
// key not found → nothing to do
|
||||
}
|
||||
|
||||
/// Prints the balance factor of every node in‑order.
|
||||
func printBalance() {
|
||||
printBalance(node: root)
|
||||
}
|
||||
|
||||
// ---------- Private helpers -------------------------------------------
|
||||
|
||||
/// Removes `node` from the tree (used by the public `delete(_:)` above).
|
||||
private func delete(_ node: Node) {
|
||||
// ----- 1️⃣ leaf node ------------------------------------------------
|
||||
if node.left == nil && node.right == nil {
|
||||
if let parent = node.parent {
|
||||
if parent.left === node { parent.left = nil }
|
||||
else { parent.right = nil }
|
||||
rebalance(parent)
|
||||
} else {
|
||||
root = nil // tree becomes empty
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ----- 2️⃣ node has a left subtree → replace with predecessor -----
|
||||
if let left = node.left {
|
||||
var predecessor = left
|
||||
while let r = predecessor.right { predecessor = r }
|
||||
node.key = predecessor.key
|
||||
delete(predecessor)
|
||||
}
|
||||
// ----- 3️⃣ otherwise it has a right subtree → replace with successor
|
||||
else if let right = node.right {
|
||||
var successor = right
|
||||
while let l = successor.left { successor = l }
|
||||
node.key = successor.key
|
||||
delete(successor)
|
||||
}
|
||||
}
|
||||
|
||||
/// Walks upward from `n`, fixing heights, balances and performing rotations.
|
||||
private func rebalance(_ n: Node) {
|
||||
setBalance(of: n)
|
||||
|
||||
var node = n
|
||||
if node.balance == -2 {
|
||||
// left heavy
|
||||
if height(of: node.left?.left) >= height(of: node.left?.right) {
|
||||
node = rotateRight(node)
|
||||
} else {
|
||||
node = rotateLeftThenRight(node)
|
||||
}
|
||||
} else if node.balance == 2 {
|
||||
// right heavy
|
||||
if height(of: node.right?.right) >= height(of: node.right?.left) {
|
||||
node = rotateLeft(node)
|
||||
} else {
|
||||
node = rotateRightThenLeft(node)
|
||||
}
|
||||
}
|
||||
|
||||
// continue upwards – or make this node the new root
|
||||
if let parent = node.parent {
|
||||
rebalance(parent)
|
||||
} else {
|
||||
root = node
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Rotations -------------------------------------------------
|
||||
|
||||
private func rotateLeft(_ a: Node) -> Node {
|
||||
guard let b = a.right else { return a } // safety guard
|
||||
|
||||
// detach b from a
|
||||
b.parent = a.parent
|
||||
a.right = b.left
|
||||
a.right?.parent = a
|
||||
|
||||
// attach a under b
|
||||
b.left = a
|
||||
a.parent = b
|
||||
|
||||
// reconnect b with the rest of the tree
|
||||
if let p = b.parent {
|
||||
if p.left === a {
|
||||
p.left = b
|
||||
} else {
|
||||
p.right = b
|
||||
}
|
||||
}
|
||||
|
||||
setBalance(of: a, b)
|
||||
return b
|
||||
}
|
||||
|
||||
private func rotateRight(_ a: Node) -> Node {
|
||||
guard let b = a.left else { return a } // safety guard
|
||||
|
||||
b.parent = a.parent
|
||||
a.left = b.right
|
||||
a.left?.parent = a
|
||||
|
||||
b.right = a
|
||||
a.parent = b
|
||||
|
||||
if let p = b.parent {
|
||||
if p.left === a {
|
||||
p.left = b
|
||||
} else {
|
||||
p.right = b
|
||||
}
|
||||
}
|
||||
|
||||
setBalance(of: a, b)
|
||||
return b
|
||||
}
|
||||
|
||||
private func rotateLeftThenRight(_ n: Node) -> Node {
|
||||
if let left = n.left {
|
||||
n.left = rotateLeft(left)
|
||||
}
|
||||
return rotateRight(n)
|
||||
}
|
||||
|
||||
private func rotateRightThenLeft(_ n: Node) -> Node {
|
||||
if let right = n.right {
|
||||
n.right = rotateRight(right)
|
||||
}
|
||||
return rotateLeft(n)
|
||||
}
|
||||
|
||||
// ---------- Height / Balance helpers ----------------------------------
|
||||
|
||||
/// Height of a node – `-1` for `nil` (matches the Java implementation).
|
||||
private func height(of node: Node?) -> Int {
|
||||
node?.height ?? -1
|
||||
}
|
||||
|
||||
/// Re‑computes stored height of `node`.
|
||||
private func reheight(_ node: Node?) {
|
||||
guard let node = node else { return }
|
||||
node.height = 1 + max(height(of: node.left), height(of: node.right))
|
||||
}
|
||||
|
||||
/// Updates both `height` and `balance` for every supplied node.
|
||||
private func setBalance(of nodes: Node...) {
|
||||
for n in nodes {
|
||||
reheight(n)
|
||||
n.balance = height(of: n.right) - height(of: n.left)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Printing ---------------------------------------------------
|
||||
|
||||
private func printBalance(node: Node?) {
|
||||
guard let node = node else { return }
|
||||
printBalance(node: node.left)
|
||||
print("\(node.balance) ", terminator: "")
|
||||
printBalance(node: node.right)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Demo -------------------------------------------------------------
|
||||
|
||||
let tree = AVLTree()
|
||||
|
||||
print("Inserting values 1 to 10")
|
||||
for i in 1...10 {
|
||||
_ = tree.insert(i)
|
||||
}
|
||||
|
||||
print("Printing balance: ", terminator: "")
|
||||
tree.printBalance()
|
||||
print() // newline
|
||||
268
Task/AVL-tree/Zig/avl-tree.zig
Normal file
268
Task/AVL-tree/Zig/avl-tree.zig
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
const std = @import("std");
|
||||
const math = std.math;
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
// AVL node
|
||||
fn AVLnode(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
key: T,
|
||||
balance: i32,
|
||||
left: ?*Self,
|
||||
right: ?*Self,
|
||||
parent: ?*Self,
|
||||
|
||||
fn init(k: T, p: ?*Self) Self {
|
||||
return Self{
|
||||
.key = k,
|
||||
.balance = 0,
|
||||
.parent = p,
|
||||
.left = null,
|
||||
.right = null,
|
||||
};
|
||||
}
|
||||
|
||||
fn deinit(self: *Self, allocator: Allocator) void {
|
||||
if (self.left) |left| {
|
||||
left.deinit(allocator);
|
||||
allocator.destroy(left);
|
||||
}
|
||||
if (self.right) |right| {
|
||||
right.deinit(allocator);
|
||||
allocator.destroy(right);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// AVL tree
|
||||
fn AVLtree(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
const Node = AVLnode(T);
|
||||
|
||||
root: ?*Node,
|
||||
allocator: Allocator,
|
||||
|
||||
fn init(allocator: Allocator) Self {
|
||||
return Self{
|
||||
.root = null,
|
||||
.allocator = allocator,
|
||||
};
|
||||
}
|
||||
|
||||
fn deinit(self: *Self) void {
|
||||
if (self.root) |root| {
|
||||
root.deinit(self.allocator);
|
||||
self.allocator.destroy(root);
|
||||
}
|
||||
}
|
||||
|
||||
fn rotateLeft(self: *Self, a: *Node) *Node {
|
||||
var b = a.right.?;
|
||||
b.parent = a.parent;
|
||||
a.right = b.left;
|
||||
|
||||
if (a.right != null) {
|
||||
a.right.?.parent = a;
|
||||
}
|
||||
|
||||
b.left = a;
|
||||
a.parent = b;
|
||||
|
||||
if (b.parent) |parent| {
|
||||
if (parent.right == a) {
|
||||
parent.right = b;
|
||||
} else {
|
||||
parent.left = b;
|
||||
}
|
||||
}
|
||||
|
||||
self.setBalance(a);
|
||||
self.setBalance(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
fn rotateRight(self: *Self, a: *Node) *Node {
|
||||
var b = a.left.?;
|
||||
b.parent = a.parent;
|
||||
a.left = b.right;
|
||||
|
||||
if (a.left != null) {
|
||||
a.left.?.parent = a;
|
||||
}
|
||||
|
||||
b.right = a;
|
||||
a.parent = b;
|
||||
|
||||
if (b.parent) |parent| {
|
||||
if (parent.right == a) {
|
||||
parent.right = b;
|
||||
} else {
|
||||
parent.left = b;
|
||||
}
|
||||
}
|
||||
|
||||
self.setBalance(a);
|
||||
self.setBalance(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
fn rotateLeftThenRight(self: *Self, n: *Node) *Node {
|
||||
n.left = self.rotateLeft(n.left.?);
|
||||
return self.rotateRight(n);
|
||||
}
|
||||
|
||||
fn rotateRightThenLeft(self: *Self, n: *Node) *Node {
|
||||
n.right = self.rotateRight(n.right.?);
|
||||
return self.rotateLeft(n);
|
||||
}
|
||||
|
||||
fn height(self: *Self, n: ?*Node) i32 {
|
||||
if (n == null)
|
||||
return -1;
|
||||
return 1 + @max(self.height(n.?.left), self.height(n.?.right));
|
||||
}
|
||||
|
||||
fn setBalance(self: *Self, n: *Node) void {
|
||||
n.balance = self.height(n.right) - self.height(n.left);
|
||||
}
|
||||
|
||||
fn rebalance(self: *Self, _n: *Node) void {
|
||||
var n=_n;
|
||||
self.setBalance(n);
|
||||
|
||||
if (n.balance == -2) {
|
||||
if (self.height(n.left.?.left) >= self.height(n.left.?.right)) {
|
||||
n = self.rotateRight(n);
|
||||
} else {
|
||||
n = self.rotateLeftThenRight(n);
|
||||
}
|
||||
} else if (n.balance == 2) {
|
||||
if (self.height(n.right.?.right) >= self.height(n.right.?.left)) {
|
||||
n = self.rotateLeft(n);
|
||||
} else {
|
||||
n = self.rotateRightThenLeft(n);
|
||||
}
|
||||
}
|
||||
|
||||
if (n.parent != null) {
|
||||
self.rebalance(n.parent.?);
|
||||
} else {
|
||||
self.root = n;
|
||||
}
|
||||
}
|
||||
|
||||
fn insert(self: *Self, key: T) !bool {
|
||||
if (self.root == null) {
|
||||
const node = try self.allocator.create(Node);
|
||||
node.* = Node.init(key, null);
|
||||
self.root = node;
|
||||
} else {
|
||||
var n = self.root.?;
|
||||
var parent: *Node = undefined;
|
||||
|
||||
while (true) {
|
||||
if (n.key == key)
|
||||
return false;
|
||||
|
||||
parent = n;
|
||||
|
||||
const goLeft = n.key > key;
|
||||
if (goLeft) {
|
||||
if (n.left) |left| {
|
||||
n = left;
|
||||
} else {
|
||||
const node = try self.allocator.create(Node);
|
||||
node.* = Node.init(key, parent);
|
||||
parent.left = node;
|
||||
self.rebalance(parent);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (n.right) |right| {
|
||||
n = right;
|
||||
} else {
|
||||
const node = try self.allocator.create(Node);
|
||||
node.* = Node.init(key, parent);
|
||||
parent.right = node;
|
||||
self.rebalance(parent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn deleteKey(self: *Self, delKey: T) void {
|
||||
if (self.root == null)
|
||||
return;
|
||||
|
||||
var n = self.root.?;
|
||||
var parent = self.root.?;
|
||||
var delNode: ?*Node = null;
|
||||
var child: ?*Node = self.root;
|
||||
|
||||
while (child != null) {
|
||||
parent = n;
|
||||
n = child.?;
|
||||
child = if (delKey >= n.key) n.right else n.left;
|
||||
if (delKey == n.key)
|
||||
delNode = n;
|
||||
}
|
||||
|
||||
if (delNode) |node| {
|
||||
node.key = n.key;
|
||||
|
||||
child = if (n.left != null) n.left else n.right;
|
||||
|
||||
if (self.root.?.key == delKey) {
|
||||
self.root = child;
|
||||
} else {
|
||||
if (parent.left == n) {
|
||||
parent.left = child;
|
||||
} else {
|
||||
parent.right = child;
|
||||
}
|
||||
|
||||
self.rebalance(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn printBalance(self: *Self, n: ?*Node) !void {
|
||||
if (n != null) {
|
||||
try self.printBalance(n.?.left);
|
||||
try stdout.print("{} ", .{n.?.balance});
|
||||
try self.printBalance(n.?.right);
|
||||
}
|
||||
}
|
||||
|
||||
fn printBalanceRoot(self: *Self) !void {
|
||||
try self.printBalance(self.root);
|
||||
try stdout.print("\n", .{});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var t = AVLtree(i32).init(allocator);
|
||||
defer t.deinit();
|
||||
|
||||
try stdout.print("Inserting integer values 1 to 10\n", .{});
|
||||
var i: i32 = 1;
|
||||
while (i <= 10) : (i += 1) {
|
||||
_ = try t.insert(i);
|
||||
}
|
||||
|
||||
try stdout.print("Printing balance: ", .{});
|
||||
try t.printBalanceRoot();
|
||||
}
|
||||
54
Task/Abbreviations-easy/ArkScript/abbreviations-easy.ark
Normal file
54
Task/Abbreviations-easy/ArkScript/abbreviations-easy.ark
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
(let commands "Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up")
|
||||
|
||||
(let user_words "riG rePEAT copies put mo rest types fup. 6 poweRin")
|
||||
|
||||
(import std.List)
|
||||
(import std.String)
|
||||
|
||||
(let abbrev_length (fun (word)
|
||||
(len
|
||||
(list:takeWhile
|
||||
word
|
||||
(fun (char) {
|
||||
(let ord (string:ord char))
|
||||
(and (<= 65 ord) (<= ord 90)) })))))
|
||||
|
||||
(let extract_cmds (fun (text)
|
||||
(list:filter (string:split text " ") (fun (elem) (not (empty? elem))))))
|
||||
|
||||
(let cmds_with_abbrev_len
|
||||
(list:map
|
||||
(extract_cmds commands)
|
||||
(fun (cmd)
|
||||
[cmd (abbrev_length cmd)] )))
|
||||
|
||||
(let find_abbrev (fun (word) {
|
||||
(let wlen (len word))
|
||||
(let lower (string:toLower word))
|
||||
|
||||
(list:map
|
||||
(list:filter
|
||||
cmds_with_abbrev_len
|
||||
(fun (cmd_with_len) {
|
||||
(let cmd (string:toLower (head cmd_with_len)))
|
||||
(let min_len (@ cmd_with_len 1))
|
||||
|
||||
(and
|
||||
(<= min_len wlen)
|
||||
(<= wlen (len cmd))
|
||||
(= lower (string:slice cmd 0 wlen))) }))
|
||||
(fun (cmd_with_len) (head cmd_with_len))) }))
|
||||
|
||||
(let user_inputs (extract_cmds user_words))
|
||||
|
||||
(assert
|
||||
(=
|
||||
["RIGHT" "REPEAT" "*error*" "PUT" "MOVE" "RESTORE" "*error*" "*error*" "*error*" "POWERINPUT"]
|
||||
(list:map
|
||||
user_inputs
|
||||
(fun (str) {
|
||||
(let abbrevs (find_abbrev str))
|
||||
(if (empty? abbrevs)
|
||||
"*error*"
|
||||
(string:toUpper (head abbrevs))) })))
|
||||
"commands were correctly deciphered")
|
||||
26
Task/Abbreviations-easy/PascalABC.NET/abbreviations-easy.pas
Normal file
26
Task/Abbreviations-easy/PascalABC.NET/abbreviations-easy.pas
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
begin
|
||||
var commands :=
|
||||
'''
|
||||
Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy
|
||||
COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find
|
||||
NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput
|
||||
Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO
|
||||
MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT
|
||||
READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT
|
||||
RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up
|
||||
'''.ToWords(AllDelimiters);
|
||||
|
||||
var countDict := commands.Each(word -> word.TakeWhile(c -> c.IsUpper).Count);
|
||||
|
||||
var correctedLine := 'riG rePEAT copies put mo rest types fup. 6 poweRin'
|
||||
.ToWords
|
||||
.Select(word ->
|
||||
commands.FirstOrDefault(
|
||||
cmd -> cmd.ToLower.StartsWith(word.ToLower) and
|
||||
(word.Length >= countDict[cmd])
|
||||
)?.ToUpper ?? '*error*'
|
||||
)
|
||||
.JoinToString;
|
||||
|
||||
Print(correctedLine);
|
||||
end.
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
{$zerobasedstrings on}
|
||||
|
||||
begin
|
||||
var commandData :=
|
||||
'''
|
||||
add 1 alter 3 backup 2 bottom 1 Cappend 2 change 1 Schange Cinsert 2 Clast 3
|
||||
compress 4 copy 2 count 3 Coverlay 3 cursor 3 delete 3 Cdelete 2 down 1 duplicate
|
||||
3 xEdit 1 expand 3 extract 3 find 1 Nfind 2 Nfindup 6 NfUP 3 Cfind 2 findUP 3 fUP 2
|
||||
forward 2 get help 1 hexType 4 input 1 powerInput 3 join 1 split 2 spltJOIN load
|
||||
locate 1 Clocate 2 lowerCase 3 upperCase 3 Lprefix 2 macro merge 2 modify 3 move 2
|
||||
msg next 1 overlay 1 parse preserve 4 purge 3 put putD query 1 quit read recover 3
|
||||
refresh renum 3 repeat 3 replace 1 Creplace 2 reset 3 restore 4 rgtLEFT right 2 left
|
||||
2 save set shift 2 si sort sos stack 3 status 4 top transfer 3 type 1 up 1
|
||||
'''.ToWords(AllDelimiters);
|
||||
|
||||
var abbrDict := Dict('' to '');
|
||||
|
||||
var i := 0;
|
||||
while i < commandData.Length do
|
||||
begin
|
||||
var cmd := commandData[i];
|
||||
i += 1;
|
||||
|
||||
// Если следующего элемента нет или он не число, используем длину команды
|
||||
var minLen := cmd.Length;
|
||||
if (i < commandData.Length) and commandData[i].All(char.IsDigit) then
|
||||
begin
|
||||
minLen := commandData[i].ToInteger;
|
||||
i += 1;
|
||||
end;
|
||||
|
||||
var cmdLower := cmd.ToLower;
|
||||
for var len := minLen to cmd.Length do
|
||||
begin
|
||||
var abbr := cmdLower[:len];
|
||||
abbrDict[abbr] := cmd.ToUpper;
|
||||
end;
|
||||
end;
|
||||
|
||||
var testStr := 'riG rePEAT copies put mo rest types fup. 6 poweRin';
|
||||
Writeln(' Input: ', testStr);
|
||||
Writeln('Output: ', testStr.ToWords()
|
||||
.Select(w -> abbrDict.Get(w.Trim.ToLower,'*error*'))
|
||||
.JoinToString);
|
||||
|
||||
testStr := '';
|
||||
Writeln(' Input: ', testStr);
|
||||
Writeln('Output: ', testStr.ToWords()
|
||||
.Select(w -> abbrDict.Get(w.Trim.ToLower,'*error*'))
|
||||
.JoinToString);
|
||||
end.
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
class Sandpile
|
||||
-- 'a' is a list of 9 integers in row order.
|
||||
function __construct(public a)
|
||||
self.neighbors = {
|
||||
{2, 4}, {1, 3, 5}, {2, 6}, {1, 5, 7}, {2, 4, 6, 8},
|
||||
{3, 5, 9}, {4, 8}, {5, 7, 9}, {6, 8}
|
||||
}
|
||||
end
|
||||
|
||||
function __add(other)
|
||||
local b = {}
|
||||
for i = 1, 9 do
|
||||
b:insert(self.a[i] + other.a[i])
|
||||
end
|
||||
return new Sandpile(b)
|
||||
end
|
||||
|
||||
function is_stable()
|
||||
return self.a:checkall(|i| -> i <= 3)
|
||||
end
|
||||
|
||||
-- Just topples once so we can observe intermediate results.
|
||||
function topple()
|
||||
for i = 1, 9 do
|
||||
if self.a[i] > 3 then
|
||||
self.a[i] -= 4
|
||||
for self.neighbors[i] as j do ++self.a[j] end
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function to_string()
|
||||
local s = ""
|
||||
for i = 1, 3 do
|
||||
for j = 1, 3 do s ..= $"{self.a[3*(i - 1) + j]} " end
|
||||
s ..= "\n"
|
||||
end
|
||||
return s
|
||||
end
|
||||
end
|
||||
|
||||
print("Avalanche of topplings:\n")
|
||||
local s0 = new Sandpile({4, 3, 3, 3, 1, 2, 0, 2, 3})
|
||||
print(s0:to_string())
|
||||
while !s0:is_stable() do
|
||||
s0:topple()
|
||||
print(s0:to_string())
|
||||
end
|
||||
|
||||
print("Commutative additions:\n")
|
||||
local s1 = new Sandpile({1, 2, 0, 2, 1, 1, 0, 1, 3})
|
||||
local s2 = new Sandpile({2, 1, 3, 1, 0, 1, 0, 1, 0})
|
||||
local s3_a = s1 + s2
|
||||
while !s3_a:is_stable() do s3_a:topple() end
|
||||
local s3_b = s2 + s1
|
||||
while !s3_b:is_stable() do s3_b:topple() end
|
||||
local s1s = s1:to_string()
|
||||
local s2s = s2:to_string()
|
||||
local s3_as = s3_a:to_string()
|
||||
local s3_bs = s3_b:to_string()
|
||||
print(string.format("%s\nplus\n\n%s\nequals\n\n%s", s1s, s2s, s3_as))
|
||||
print(string.format("and\n\n%s\nplus\n\n%s\nalso equals\n\n%s", s2s, s1s, s3_bs))
|
||||
|
||||
print("Addition of identity sandpile:\n")
|
||||
local s3 = new Sandpile({3, 3, 3, 3, 3, 3, 3, 3, 3})
|
||||
local s3_id = new Sandpile({2, 1, 2, 1, 0, 1, 2, 1, 2})
|
||||
local s4 = s3 + s3_id
|
||||
while !s4:is_stable() do s4:topple() end
|
||||
local s3s = s3:to_string()
|
||||
local s3_ids = s3_id:to_string()
|
||||
local s4s = s4:to_string()
|
||||
print(string.format("%s\nplus\n\n%s\nequals\n\n%s", s3s, s3_ids, s4s))
|
||||
|
||||
print("Addition of identities:\n")
|
||||
local s5 = s3_id + s3_id
|
||||
while !s5:is_stable() do s5:topple() end
|
||||
local s5s = s5:to_string()
|
||||
print(string.format("%s\nplus\n\n%s\nequals\n\n%s", s3_ids, s3_ids, s5s))
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
const std = @import("std");
|
||||
|
||||
const Box = struct {
|
||||
piles: [3][3]u8,
|
||||
|
||||
fn init(piles: [3][3]u8) Box {
|
||||
var a = Box{ .piles = piles };
|
||||
|
||||
for (a.piles) |row| {
|
||||
for (row) |pile| {
|
||||
if (pile >= 4) {
|
||||
return a.avalanche();
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
fn avalanche(self: *const Box) Box {
|
||||
var a = self.*;
|
||||
for (self.piles, 0..) |row, i| {
|
||||
for (row, 0..) |pile, j| {
|
||||
if (pile >= 4) {
|
||||
if (i > 0) {
|
||||
a.piles[i - 1][j] += 1;
|
||||
}
|
||||
if (i < 2) {
|
||||
a.piles[i + 1][j] += 1;
|
||||
}
|
||||
if (j > 0) {
|
||||
a.piles[i][j - 1] += 1;
|
||||
}
|
||||
if (j < 2) {
|
||||
a.piles[i][j + 1] += 1;
|
||||
}
|
||||
a.piles[i][j] -= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Box.init(a.piles);
|
||||
}
|
||||
|
||||
fn add(self: *const Box, other: *const Box) Box {
|
||||
var b = Box{
|
||||
.piles = [_][3]u8{[_]u8{0} ** 3} ** 3,
|
||||
};
|
||||
for (0..3) |row| {
|
||||
for (0..3) |col| {
|
||||
b.piles[row][col] = self.piles[row][col] + other.piles[row][col];
|
||||
}
|
||||
}
|
||||
return Box.init(b.piles);
|
||||
}
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
|
||||
try stdout.print("The piles demonstration avalanche starts as:\n{any}\n{any}\n{any}\n", .{
|
||||
[_]u8{ 4, 3, 3 },
|
||||
[_]u8{ 3, 1, 2 },
|
||||
[_]u8{ 0, 2, 3 },
|
||||
});
|
||||
|
||||
const s0 = Box.init([_][3]u8{
|
||||
[_]u8{ 4, 3, 3 },
|
||||
[_]u8{ 3, 1, 2 },
|
||||
[_]u8{ 0, 2, 3 },
|
||||
});
|
||||
|
||||
try stdout.print("And ends as:\n{any}\n{any}\n{any}\n", .{
|
||||
s0.piles[0],
|
||||
s0.piles[1],
|
||||
s0.piles[2],
|
||||
});
|
||||
|
||||
const s1 = Box.init([_][3]u8{
|
||||
[_]u8{ 1, 2, 0 },
|
||||
[_]u8{ 2, 1, 1 },
|
||||
[_]u8{ 0, 1, 3 },
|
||||
});
|
||||
|
||||
const s2 = Box.init([_][3]u8{
|
||||
[_]u8{ 2, 1, 3 },
|
||||
[_]u8{ 1, 0, 1 },
|
||||
[_]u8{ 0, 1, 0 },
|
||||
});
|
||||
|
||||
const s1_2 = s1.add(&s2);
|
||||
const s2_1 = s2.add(&s1);
|
||||
|
||||
try stdout.print("The piles in s1 + s2 are:\n{any}\n{any}\n{any}\n", .{
|
||||
s1_2.piles[0],
|
||||
s1_2.piles[1],
|
||||
s1_2.piles[2],
|
||||
});
|
||||
|
||||
try stdout.print("The piles in s2 + s1 are:\n{any}\n{any}\n{any}\n", .{
|
||||
s2_1.piles[0],
|
||||
s2_1.piles[1],
|
||||
s2_1.piles[2],
|
||||
});
|
||||
|
||||
const s3 = Box.init([_][3]u8{[_]u8{3} ** 3} ** 3);
|
||||
const s3_id = Box.init([_][3]u8{
|
||||
[_]u8{ 2, 1, 2 },
|
||||
[_]u8{ 1, 0, 1 },
|
||||
[_]u8{ 2, 1, 2 },
|
||||
});
|
||||
|
||||
const s4 = s3.add(&s3_id);
|
||||
|
||||
try stdout.print("The piles in s3 + s3_id are:\n{any}\n{any}\n{any}\n", .{
|
||||
s4.piles[0],
|
||||
s4.piles[1],
|
||||
s4.piles[2],
|
||||
});
|
||||
|
||||
const s5 = s3_id.add(&s3_id);
|
||||
|
||||
try stdout.print("The piles in s3_id + s3_id are:\n{any}\n{any}\n{any}\n", .{
|
||||
s5.piles[0],
|
||||
s5.piles[1],
|
||||
s5.piles[2],
|
||||
});
|
||||
}
|
||||
|
|
@ -1,24 +1,25 @@
|
|||
module AbelSand
|
||||
""" From code by Hayk Aleksanyan, see also github.com/hayk314/Sandpiles """
|
||||
|
||||
# supports output functionality for the results of the sandpile simulations
|
||||
# outputs the final grid in CSV format, as well as an image file
|
||||
""" supports output functionality for the results of the sandpile simulations
|
||||
outputs the final grid in CSV format, as well as an image file
|
||||
"""
|
||||
module AbelSand
|
||||
|
||||
using CSV, DataFrames, Images
|
||||
|
||||
function TrimZeros(A)
|
||||
# given an array A trims any zero rows/columns from its borders
|
||||
# returns a 4 tuple of integers, i1, i2, j1, j2, where the trimmed array corresponds to A[i1:i2, j1:j2]
|
||||
# A can be either numeric or a boolean array
|
||||
|
||||
""" given an array A trims any zero rows/columns from its borders
|
||||
returns a 4 tuple of integers, i1, i2, j1, j2, where the trimmed array corresponds to A[i1:i2, j1:j2]
|
||||
A can be either numeric or a boolean array
|
||||
"""
|
||||
function trimzeros(A)
|
||||
i1, j1 = 1, 1
|
||||
i2, j2 = size(A)
|
||||
|
||||
zz = typeof(A[1, 1])(0) # comparison of a value takes into account the type as well
|
||||
|
||||
# i1 is the first row which has non zero element
|
||||
for i = 1:size(A, 1)
|
||||
for i in axes(A, 1)
|
||||
q = false
|
||||
for k = 1:size(A, 2)
|
||||
for k in axes(A, 2)
|
||||
if A[i, k] != zz
|
||||
q = true
|
||||
i1 = i
|
||||
|
|
@ -32,26 +33,24 @@ function TrimZeros(A)
|
|||
end
|
||||
|
||||
# i2 is the first from below row with non zero element
|
||||
for i in size(A, 1):-1:1
|
||||
for i in reverse(axes(A, 1))
|
||||
q = false
|
||||
for k = 1:size(A, 2)
|
||||
for k in axes(A, 2)
|
||||
if A[i, k] != zz
|
||||
q = true
|
||||
i2 = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if q == true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# j1 is the first column with non zero element
|
||||
|
||||
for j = 1:size(A, 2)
|
||||
for j in axes(A, 2)
|
||||
q = false
|
||||
for k = 1:size(A, 1)
|
||||
for k in axes(A, 1)
|
||||
if A[k, j] != zz
|
||||
j1 = j
|
||||
q = true
|
||||
|
|
@ -65,18 +64,17 @@ function TrimZeros(A)
|
|||
end
|
||||
|
||||
# j2 is the last column with non zero element
|
||||
|
||||
for j in size(A, 2):-1:1
|
||||
q=false
|
||||
for k=1:size(A,1)
|
||||
for j in reverse(axes(A, 2))
|
||||
q = false
|
||||
for k in axes(A, 1)
|
||||
if A[k, j] != zz
|
||||
j2 = j
|
||||
q=true
|
||||
q = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if q==true
|
||||
if q == true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
|
@ -84,129 +82,124 @@ function TrimZeros(A)
|
|||
return i1, i2, j1, j2
|
||||
end
|
||||
|
||||
function addLayerofZeros(A, extraLayer)
|
||||
# adds layer of zeros from all corners to the given array A
|
||||
|
||||
if extraLayer <= 0
|
||||
return A
|
||||
end
|
||||
""" adds layer of zeros from all corners to the given array A """
|
||||
function addlayerofzeros!(A, extraLayer)
|
||||
extraLayer <= 0 && return A
|
||||
|
||||
N, M = size(A)
|
||||
|
||||
|
||||
Z = zeros( typeof(A[1,1]), N + 2*extraLayer, M + 2*extraLayer)
|
||||
Z[(extraLayer+1):(N + extraLayer ), (extraLayer+1):(M+extraLayer)] = A
|
||||
Z = zeros(typeof(A[1, 1]), N + 2 * extraLayer, M + 2 * extraLayer)
|
||||
Z[(extraLayer+1):(N+extraLayer), (extraLayer+1):(M+extraLayer)] = A
|
||||
|
||||
return Z
|
||||
|
||||
end
|
||||
|
||||
function printIntoFile(A, extraLayer, strFileName, TrimSmallValues = false)
|
||||
# exports a 2d matrix A into a csv file
|
||||
# @extraLayer is an integers adding layer of 0-s sorrounding the output matrix
|
||||
|
||||
# trimming off very small values; tiny values affect the performance of CSV export
|
||||
""" exports a 2d matrix A into a csv file, adjusting the size of the output matrix
|
||||
@extraLayer is an integers adding layer of 0-s sorrounding the output matrix
|
||||
trimming off very small values; tiny values affect the performance of CSV export
|
||||
"""
|
||||
function outputCSV!(A, extraLayer, strFileName, TrimSmallValues = false)
|
||||
if TrimSmallValues == true
|
||||
A = map(x -> if (abs(x - floor(x)) < 0.01) floor(x) else x end, A)
|
||||
A = map(x -> if (abs(x - floor(x)) < 0.01)
|
||||
floor(x)
|
||||
else
|
||||
x
|
||||
end, A)
|
||||
end
|
||||
|
||||
i1, i2, j1, j2 = TrimZeros( A )
|
||||
i1, i2, j1, j2 = trimzeros(A)
|
||||
A = A[i1:i2, j1:j2]
|
||||
|
||||
A = addLayerofZeros(A, extraLayer)
|
||||
|
||||
CSV.write(string(strFileName,".csv"), DataFrame(A), writeheader = false)
|
||||
A = addlayerofzeros!(A, extraLayer)
|
||||
CSV.write(string(strFileName, ".csv"), DataFrame(A, :auto), writeheader = false)
|
||||
|
||||
return A
|
||||
|
||||
end
|
||||
|
||||
function Array_magnifier(A, cell_mag, border_mag)
|
||||
# A is the main array; @cell_mag is the magnifying size of the cell,
|
||||
# @border_mag is the magnifying size of the border between lattice cells
|
||||
|
||||
# creates a new array where each cell of the original array A appears magnified by size = cell_mag
|
||||
|
||||
|
||||
""" creates a new array A1 where each cell of the original array A appears magnified by size @cell_mag
|
||||
A is the input array; @cell_mag is the magnifying size of the cell,
|
||||
@border_mag is the magnifying size of the border between lattice cells
|
||||
"""
|
||||
function arraymagnifier(A, cell_mag, border_mag)
|
||||
total_factor = cell_mag + border_mag
|
||||
A1 = zeros(typeof(A[1, 1]), total_factor * size(A, 1), total_factor * size(A, 2))
|
||||
for i ∈ axes(A, 1), j ∈ axes(A, 2), u ∈ ((i-1)*total_factor+1):(i*total_factor),
|
||||
v ∈ ((j-1)*total_factor+1):(j*total_factor)
|
||||
|
||||
A1 = zeros(typeof(A[1, 1]), total_factor*size(A, 1), total_factor*size(A, 2))
|
||||
|
||||
for i = 1:size(A,1), j = 1:size(A,2), u = ((i-1)*total_factor+1):(i*total_factor),
|
||||
v = ((j-1)*total_factor+1):(j*total_factor)
|
||||
if(( u - (i - 1) * total_factor <= cell_mag) && (v - (j - 1) * total_factor <= cell_mag))
|
||||
if ((u - (i - 1) * total_factor <= cell_mag) && (v - (j - 1) * total_factor <= cell_mag))
|
||||
A1[u, v] = A[i, j]
|
||||
end
|
||||
end
|
||||
|
||||
return A1
|
||||
|
||||
end
|
||||
|
||||
function saveAsGrayImage(A, fileName, cell_mag, border_mag, TrimSmallValues = false)
|
||||
# given a 2d matrix A, we save it as a gray image after magnifying by the given factors
|
||||
A1 = Array_magnifier(A, cell_mag, border_mag)
|
||||
A1 = A1/maximum(maximum(A1))
|
||||
""" given a 2d matrix A, we save it as a gray image after magnifying by the given factors """
|
||||
function savegrayimage(A, fileName, cell_mag, border_mag, TrimSmallValues = false)
|
||||
A1 = arraymagnifier(A, cell_mag, border_mag)
|
||||
A1 = A1 / maximum(maximum(A1))
|
||||
|
||||
# trimming very small values from A1 to improve performance
|
||||
if TrimSmallValues == true
|
||||
A1 = map(x -> if ( x < 0.01) 0.0 else round(x, digits = 2) end, A1)
|
||||
A1 = map(x -> if (x < 0.01)
|
||||
0.0
|
||||
else
|
||||
round(x, digits = 2)
|
||||
end, A1)
|
||||
end
|
||||
|
||||
save(string(fileName, ".png") , colorview(Gray, A1))
|
||||
save(string(fileName, ".png"), colorview(Gray, A1))
|
||||
end
|
||||
|
||||
function saveAsRGBImage(A, fileName, color_codes, cell_mag, border_mag)
|
||||
# color_codes is a dictionary, where key is a value in A and value is an RGB triplet
|
||||
# given a 2d array A, and color codes (mapping from values in A to RGB triples), save A
|
||||
# into fileName as png image after applying the magnifying factors
|
||||
|
||||
A1 = Array_magnifier(A, cell_mag, border_mag)
|
||||
""" color_codes is a dictionary, where key is a value in A and value is an RGB triplet
|
||||
given a 2d array A, and color codes (mapping from values in A to RGB triples), save A
|
||||
into fileName as png image after applying the magnifying factors
|
||||
"""
|
||||
function saveRGBimage(A, fileName, color_codes, cell_mag, border_mag)
|
||||
A1 = arraymagnifier(A, cell_mag, border_mag)
|
||||
color_mat = zeros(UInt8, (3, size(A1, 1), size(A1, 2)))
|
||||
|
||||
for i = 1:size(A1,1)
|
||||
for j = 1:size(A1,2)
|
||||
color_mat[:, i, j] = get(color_codes, A1[i, j] , [0, 0, 0])
|
||||
for i in axes(A1, 1)
|
||||
for j in axes(A1, 2)
|
||||
color_mat[:, i, j] = get(color_codes, A1[i, j], [0, 0, 0])
|
||||
end
|
||||
end
|
||||
|
||||
save(string(fileName, ".png") , colorview(RGB, color_mat/255))
|
||||
save(string(fileName, ".png"), colorview(RGB, color_mat / 255))
|
||||
end
|
||||
|
||||
const N_size = 700 # the radius of the lattice Z^2, the actual size becomes (2*N+1)x(2*N+1)
|
||||
const dx = [1, 0, -1, 0] # for a given (x,y) in Z^2, (x + dx, y + dy) for all (dx,dy) covers the neighborhood of (x,y)
|
||||
const dy = [0, 1, 0, -1]
|
||||
|
||||
""" represents a 2D lattice coordinate """
|
||||
struct L_coord
|
||||
# represents a lattice coordinate
|
||||
x::Int
|
||||
y::Int
|
||||
end
|
||||
|
||||
function FindCoordinate(Z::Array{L_coord,1}, a::Int, b::Int)
|
||||
# in the given array Z of coordinates finds the (first) index of the tuple (a,b)
|
||||
# if no match, returns -1
|
||||
|
||||
for i=1:length(Z)
|
||||
""" Finds the (first) index of the tuple (a,b) in the given array Z of coordinates
|
||||
if no match, returns -1
|
||||
"""
|
||||
function findcoordinate(Z::Array{L_coord, 1}, a::Int, b::Int)
|
||||
for i ∈ 1:length(Z)
|
||||
if (Z[i].x == a) && (Z[i].y == b)
|
||||
return i
|
||||
end
|
||||
end
|
||||
|
||||
return -1
|
||||
end
|
||||
|
||||
function move(N)
|
||||
# the main function moving the pile sand grains of size N at the origin of Z^2 until the sandpile becomes stable
|
||||
|
||||
""" Moves the pile's sand grains of size N stacked all at the origin of Z^2
|
||||
until the sandpile settled to stable configuration.
|
||||
Returns the final lattice Z_lat and the odometer Odometer
|
||||
"""
|
||||
function settle(N)
|
||||
Z_lat = zeros(UInt8, 2 * N_size + 1, 2 * N_size + 1) # models the integer lattice Z^2, we will have at most 4 sands on each vertex
|
||||
V_sites = falses(2 * N_size + 1, 2 * N_size + 1) # all sites which are visited by the sandpile process, are being marked here
|
||||
Odometer = zeros(UInt64, 2 * N_size + 1, 2 * N_size + 1) # stores the values of the odometer function
|
||||
|
||||
|
||||
walking = L_coord[] # the coordinates of sites which need to move
|
||||
|
||||
V_sites[N_size + 1, N_size + 1] = true
|
||||
V_sites[N_size+1, N_size+1] = true
|
||||
|
||||
# i1, ... j2 -> show the boundaries of the box which is visited by the sandpile process
|
||||
i1, i2, j1, j2 = N_size + 1, N_size + 1, N_size + 1, N_size + 1
|
||||
|
|
@ -217,12 +210,12 @@ function move(N)
|
|||
while n > 0
|
||||
n -= 1
|
||||
|
||||
Z_lat[N_size + 1, N_size + 1] += 1
|
||||
if (Z_lat[N_size + 1, N_size + 1] >= 4)
|
||||
Z_lat[N_size+1, N_size+1] += 1
|
||||
if (Z_lat[N_size+1, N_size+1] >= 4)
|
||||
push!(walking, L_coord(N_size + 1, N_size + 1))
|
||||
end
|
||||
|
||||
while(length(walking) > 0)
|
||||
while (length(walking) > 0)
|
||||
w = pop!(walking)
|
||||
x = w.x
|
||||
y = w.y
|
||||
|
|
@ -230,12 +223,12 @@ function move(N)
|
|||
Z_lat[x, y] -= 4
|
||||
Odometer[x, y] += 4
|
||||
|
||||
for k = 1:4
|
||||
Z_lat[x + dx[k], y + dy[k]] += 1
|
||||
V_sites[x + dx[k], y + dy[k]] = true
|
||||
if Z_lat[x + dx[k], y + dy[k]] >= 4
|
||||
if FindCoordinate(walking, x + dx[k] , y + dy[k]) == -1
|
||||
push!(walking, L_coord( x + dx[k], y + dy[k]))
|
||||
for k ∈ 1:4
|
||||
Z_lat[x+dx[k], y+dy[k]] += 1
|
||||
V_sites[x+dx[k], y+dy[k]] = true
|
||||
if Z_lat[x+dx[k], y+dy[k]] >= 4
|
||||
if findcoordinate(walking, x + dx[k], y + dy[k]) == -1
|
||||
push!(walking, L_coord(x + dx[k], y + dy[k]))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -247,29 +240,24 @@ function move(N)
|
|||
end
|
||||
|
||||
|
||||
end #end of the main while
|
||||
end # of the outer while
|
||||
t2 = time_ns()
|
||||
|
||||
println("The final boundaries are:: ", (i2 - i1 + 1),"x",(j2 - j1 + 1), "\n")
|
||||
print("time elapsed: " , (t2 - t1) / 1.0e9, "\n")
|
||||
println("The final boundaries are:: ", (i2 - i1 + 1), "x", (j2 - j1 + 1), "\n")
|
||||
print("time elapsed: ", (t2 - t1) / 1.0e9, "\n")
|
||||
|
||||
Z_lat = printIntoFile(Z_lat, 0, string("Abel_Z_", N))
|
||||
Odometer = printIntoFile(Odometer, 1, string("Abel_OD_", N))
|
||||
Z_lat = outputCSV!(Z_lat, 0, string("Abel_Z_", N))
|
||||
Odometer = outputCSV!(Odometer, 1, string("Abel_OD_", N))
|
||||
|
||||
saveAsGrayImage(Z_lat, string("Abel_Z_", N), 20, 0)
|
||||
color_code = Dict(1=>[255, 128, 255], 2=>[255, 0, 0],3 => [0, 128, 255])
|
||||
saveAsRGBImage(Z_lat, string("Abel_Z_color_", N), color_code, 20, 0)
|
||||
savegrayimage(Z_lat, string("Abel_Z_", N), 20, 0)
|
||||
color_code = Dict(1 => [255, 128, 255], 2 => [255, 0, 0], 3 => [0, 128, 255])
|
||||
saveRGBimage(Z_lat, string("Abel_Z_color_", N), color_code, 20, 0)
|
||||
|
||||
# for the total elapsed time, it's better to use the @time macros on the main call
|
||||
|
||||
return Z_lat, Odometer # these are trimmed in output module
|
||||
|
||||
end # end of function move
|
||||
|
||||
|
||||
end # module
|
||||
return Z_lat, Odometer
|
||||
end
|
||||
|
||||
end # of the module
|
||||
|
||||
using .AbelSand
|
||||
|
||||
Z_lat, Odometer = AbelSand.move(100000)
|
||||
Z_lat, Odometer = AbelSand.settle(100000)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
class Sandpile
|
||||
-- 'a' is a list of integers in row order.
|
||||
function __construct(a)
|
||||
local count = #a
|
||||
self.rows = math.floor(math.sqrt(count))
|
||||
if self.rows * self.rows != count then
|
||||
print("The matrix of values must be square.")
|
||||
os.exit(1)
|
||||
end
|
||||
self.a = a
|
||||
self.neighbors = {}
|
||||
for i = 1, count do
|
||||
self.neighbors[i] = {}
|
||||
if (i - 1) % self.rows > 0 then self.neighbors[i]:insert(i - 1) end
|
||||
if i % self.rows > 0 then self.neighbors[i]:insert(i + 1) end
|
||||
if i - self.rows >= 1 then self.neighbors[i]:insert(i - self.rows) end
|
||||
if i + self.rows < count + 1 then self.neighbors[i]:insert(i + self.rows) end
|
||||
end
|
||||
end
|
||||
|
||||
function is_stable()
|
||||
return self.a:checkall(|i| -> i <= 3)
|
||||
end
|
||||
|
||||
-- Topples until stable.
|
||||
function topple()
|
||||
while !self:is_stable() do
|
||||
for i = 1, #self.a do
|
||||
if self.a[i] > 3 then
|
||||
self.a[i] -= 4
|
||||
for self.neighbors[i] as j do ++self.a[j] end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function to_string()
|
||||
local s = ""
|
||||
for i = 1, self.rows do
|
||||
for j = 1, self.rows do
|
||||
s ..= string.format("%2d ", self.a[self.rows * (i - 1) + j])
|
||||
end
|
||||
s ..="\n"
|
||||
end
|
||||
return s
|
||||
end
|
||||
end
|
||||
|
||||
local function print_across(str1, str2)
|
||||
local r1 = str1:split("\n")
|
||||
local r2 = str2:split("\n")
|
||||
local rows = #r1 - 1
|
||||
local cr = rows // 2 + 1
|
||||
for i = 1, rows do
|
||||
local symbol = (i == cr) ? "->" : " "
|
||||
print(string.format("%s %s %s", r1[i], symbol, r2[i]))
|
||||
end
|
||||
print()
|
||||
end
|
||||
|
||||
local a1, a2, a3, a4 = {}, {}, {}, {}
|
||||
for i = 1, 25 do
|
||||
a1[i] = 0
|
||||
a2[i] = 0
|
||||
a3[i] = 0
|
||||
end
|
||||
for i = 1, 100 do
|
||||
a4[i] = 0
|
||||
end
|
||||
a1[13] = 4
|
||||
a2[13] = 6
|
||||
a3[13] = 16
|
||||
a4[56] = 64
|
||||
for {a1, a2, a3, a4} as a do
|
||||
local s = new Sandpile(a)
|
||||
local str1 = s:to_string()
|
||||
s:topple()
|
||||
local str2 = s:to_string()
|
||||
print_across(str1, str2)
|
||||
end
|
||||
136
Task/Abelian-sandpile-model/Zig/abelian-sandpile-model.zig
Normal file
136
Task/Abelian-sandpile-model/Zig/abelian-sandpile-model.zig
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
const std = @import("std");
|
||||
|
||||
/// It loops over the current state of the sandpile and updates it on-the-fly.
|
||||
fn advance(field: [][]usize, boundary: *[4]usize) bool {
|
||||
// This variable is used to check whether we changed anything in the array. If no, the loop terminates.
|
||||
var done = false;
|
||||
|
||||
var y = boundary[0];
|
||||
while (y < boundary[2]) : (y += 1) {
|
||||
var x = boundary[1];
|
||||
while (x < boundary[3]) : (x += 1) {
|
||||
if (field[y][x] >= 4) {
|
||||
// This part was heavily inspired by the Pascal version. We subtract 4 as many times as we can
|
||||
// and distribute it to the neighbors. Also, in case we have outgrown the current boundary, we
|
||||
// update it to once again contain the entire sandpile.
|
||||
|
||||
// The amount that gets added to the neighbors is the amount here divided by four and (implicitly) floored.
|
||||
// The remaining sand is just current modulo 4.
|
||||
const rem: usize = field[y][x] / 4;
|
||||
field[y][x] = field[y][x] % 4;
|
||||
|
||||
if (y > 0) {
|
||||
field[y - 1][x] += rem;
|
||||
if (y == boundary[0]) {
|
||||
boundary[0] -= 1;
|
||||
}
|
||||
}
|
||||
if (x > 0) {
|
||||
field[y][x - 1] += rem;
|
||||
if (x == boundary[1]) {
|
||||
boundary[1] -= 1;
|
||||
}
|
||||
}
|
||||
if (y + 1 < field.len) {
|
||||
field[y + 1][x] += rem;
|
||||
if (y == boundary[2] - 1) {
|
||||
boundary[2] += 1;
|
||||
}
|
||||
}
|
||||
if (x + 1 < field.len) {
|
||||
field[y][x + 1] += rem;
|
||||
if (x == boundary[3] - 1) {
|
||||
boundary[3] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
/// This function can be used to display the sandpile in the console window.
|
||||
fn display(field: [][]usize) void {
|
||||
for (field) |row| {
|
||||
for (row) |cell| {
|
||||
const c: u8 = switch (cell) {
|
||||
0 => ' ',
|
||||
1 => '.',
|
||||
2 => 'o',
|
||||
3 => 'O',
|
||||
else => '#',
|
||||
};
|
||||
std.debug.print("{c}", .{c});
|
||||
}
|
||||
std.debug.print("\n", .{});
|
||||
}
|
||||
}
|
||||
|
||||
/// This function writes the end result to a file called "output.ppm".
|
||||
fn write_pile(pile: [][]usize, allocator: std.mem.Allocator) !void {
|
||||
// We first create the file (or erase its contents if it already existed).
|
||||
const file = try std.fs.cwd().createFile("output.ppm", .{});
|
||||
defer file.close();
|
||||
|
||||
// Then we add the image signature, which is "P3 <newline>[width of image] [height of image]<newline>[maximum value of color]<newline>".
|
||||
try std.fmt.format(file.writer(), "P3\n{d} {d}\n255\n", .{ pile.len, pile.len });
|
||||
|
||||
for (pile) |row| {
|
||||
var line = std.ArrayList(u8).init(allocator);
|
||||
defer line.deinit();
|
||||
|
||||
// We map each value in the field to a color.
|
||||
for (row) |elem| {
|
||||
const color = switch (elem) {
|
||||
0 => "100 40 15 ",
|
||||
1 => "117 87 30 ",
|
||||
2 => "181 134 47 ",
|
||||
3 => "245 182 66 ",
|
||||
else => unreachable,
|
||||
};
|
||||
try line.appendSlice(color);
|
||||
}
|
||||
|
||||
try std.fmt.format(file.writer(), "{s}\n", .{line.items});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
// This is how big the final image will be. Currently the end result would be a 16x16 picture.
|
||||
const field_size: usize = 16;
|
||||
|
||||
// Create the 2D array
|
||||
var playfield = try allocator.alloc([]usize, field_size);
|
||||
defer {
|
||||
for (playfield) |row| {
|
||||
allocator.free(row);
|
||||
}
|
||||
allocator.free(playfield);
|
||||
}
|
||||
|
||||
for (playfield, 0..) |_, i| {
|
||||
playfield[i] = try allocator.alloc(usize, field_size);
|
||||
@memset(playfield[i], 0);
|
||||
}
|
||||
|
||||
// We put the initial sand in the exact middle of the field.
|
||||
// This isn't necessary per se, but it ensures that sand can fully topple.
|
||||
var boundary = [4]usize{ field_size / 2 - 1, field_size / 2 - 1, field_size / 2, field_size / 2 };
|
||||
playfield[field_size / 2 - 1][field_size / 2 - 1] = 16;
|
||||
|
||||
// This is the main loop. We update the field until it returns false, signalling that the pile reached its
|
||||
// final state.
|
||||
while (advance(playfield, &boundary)) {}
|
||||
|
||||
// Once this happens, we simply display the result. Uncomment the line below to write it to a file.
|
||||
// Calling display with large field sizes is not recommended as it can easily become too large for the console.
|
||||
display(playfield);
|
||||
// try write_pile(playfield, allocator);
|
||||
}
|
||||
60
Task/Abstract-type/Free-Pascal-Lazarus/abstract-type-1.pas
Normal file
60
Task/Abstract-type/Free-Pascal-Lazarus/abstract-type-1.pas
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
program abstracts;
|
||||
// this code also compiles in delphi
|
||||
{$ifdef fpc}{$mode objfpc}{$endif}
|
||||
type
|
||||
// Pure Abstract Class. In cs theory also known as an interface,
|
||||
// because it has no implementation
|
||||
TAbstractClass = class abstract
|
||||
protected
|
||||
function noise:string;virtual;abstract;
|
||||
end;
|
||||
// classic inheritance
|
||||
Tdog = class(TAbstractClass)
|
||||
public
|
||||
function noise:string;override;
|
||||
end;
|
||||
|
||||
Tcat = class(TAbstractClass)
|
||||
public
|
||||
function noise:string;override;
|
||||
end;
|
||||
|
||||
// unrelated class that matches the interface of TAbstractClass, the VMT.
|
||||
Tbird = class
|
||||
strict private
|
||||
FField:string;
|
||||
function noise:string;virtual;
|
||||
property field:string read FField write FField;
|
||||
end;
|
||||
|
||||
function Tdog.Noise:string;
|
||||
begin
|
||||
Result := 'Woof';
|
||||
end;
|
||||
|
||||
function Tcat.Noise:string;
|
||||
begin
|
||||
Result := 'Miauw';
|
||||
end;
|
||||
|
||||
function TBird.Noise:string;
|
||||
begin
|
||||
Result := 'Tjirpp';
|
||||
end;
|
||||
|
||||
var
|
||||
cat, dog: TAbstractClass;
|
||||
bird:Tbird;
|
||||
begin
|
||||
cat := Tcat.Create;
|
||||
dog := Tdog.Create;
|
||||
bird := TBird.Create;
|
||||
writeln(cat.noise,dog.noise);
|
||||
// even this works, because the layout is the same
|
||||
// This is similar to C++, where pure abstract classes are interfaces.
|
||||
writeln(TAbstractClass(bird).noise);
|
||||
bird.free;
|
||||
dog.free;
|
||||
cat.free;
|
||||
readln;
|
||||
end.
|
||||
32
Task/Abstract-type/Free-Pascal-Lazarus/abstract-type-2.pas
Normal file
32
Task/Abstract-type/Free-Pascal-Lazarus/abstract-type-2.pas
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
program justasabstract;
|
||||
{$ifdef fpc}{$mode objfpc}{$endif}
|
||||
type
|
||||
IAnimalInterface = interface
|
||||
['{BD40E312-36AD-4F8B-A3EF-727F2474E494}']
|
||||
function noise:string;
|
||||
function move:string;
|
||||
end;
|
||||
|
||||
Tbird = class(TInterfacedObject,IAnimalInterface)
|
||||
strict private
|
||||
function noise:string;virtual;
|
||||
function move:string;virtual;
|
||||
end;
|
||||
|
||||
function TBird.Noise:string;
|
||||
begin
|
||||
Result := 'Tjirpp';
|
||||
end;
|
||||
|
||||
function TBird.move:string;
|
||||
begin
|
||||
Result := 'I fly';
|
||||
end;
|
||||
|
||||
var
|
||||
bird:IAnimalInterface; // as interface, this unhides the strict private methods too.
|
||||
begin
|
||||
bird := TBird.Create;
|
||||
writeln(bird.noise);
|
||||
writeln(bird.move);
|
||||
end.
|
||||
44
Task/Abstract-type/Haxe/abstract-type-1.haxe
Normal file
44
Task/Abstract-type/Haxe/abstract-type-1.haxe
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
interface Vocal {
|
||||
public function speak():String;
|
||||
}
|
||||
|
||||
interface Gravitational {
|
||||
public function getWeight():Int;
|
||||
}
|
||||
|
||||
abstract class Dog implements Vocal implements Gravitational {
|
||||
public function speak():String {
|
||||
return "Woof";
|
||||
}
|
||||
|
||||
public function new() {}
|
||||
}
|
||||
|
||||
class Chihuahua extends Dog {
|
||||
public function getWeight():Int {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
class GreatDane extends Dog {
|
||||
public function getWeight():Int {
|
||||
return 150;
|
||||
}
|
||||
}
|
||||
|
||||
class Main {
|
||||
static public function main():Void {
|
||||
var dogs:Array<Dog> = [];
|
||||
|
||||
var david = new Chihuahua();
|
||||
var goliath = new GreatDane();
|
||||
|
||||
dogs.push(david);
|
||||
dogs.push(goliath);
|
||||
|
||||
for (dog in dogs) {
|
||||
trace(dog.speak());
|
||||
trace(dog.getWeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Task/Abstract-type/Pluto/abstract-type.pluto
Normal file
34
Task/Abstract-type/Pluto/abstract-type.pluto
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
class Beast
|
||||
function __construct()
|
||||
error("Instantiation not allowed as class is abstract.")
|
||||
end
|
||||
|
||||
function kind() end
|
||||
function name() end
|
||||
function cry() end
|
||||
|
||||
function print()
|
||||
print($'{self:name()}, who\'s a {self:kind()}, cries: "{self:cry()}".')
|
||||
end
|
||||
end
|
||||
|
||||
class Dog extends Beast
|
||||
function __construct(private kind, private name) end
|
||||
|
||||
function kind() return self.kind end
|
||||
function name() return self.name end
|
||||
function cry() return "Woof" end
|
||||
end
|
||||
|
||||
class Cat extends Beast
|
||||
function __construct(private kind, private name) end
|
||||
|
||||
function kind() return self.kind end
|
||||
function name() return self.name end
|
||||
function cry() return "Meow" end
|
||||
end
|
||||
|
||||
local d = new Dog("labrador", "Max")
|
||||
local c = new Cat("siamese", "Sammy")
|
||||
d:print()
|
||||
c:print()
|
||||
|
|
@ -40,5 +40,5 @@ s: make shape [] s/draw ; Nothing happens.
|
|||
print "A box:"
|
||||
b: make box [pen: "O" size: 5] b/draw
|
||||
|
||||
print [crlf "A rectangle:"]
|
||||
print "^/A rectangle:"
|
||||
r: make rectangle [size: 32x5] r/draw
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
scope # count abundant, perfect and deficient numbers up to 20 000
|
||||
# construct a table of proper divisor sums
|
||||
local constant MAX_NUMBER, constant pds := 20_000, seq();
|
||||
pds[ 1 ] := 0;
|
||||
for i from 2 to MAX_NUMBER do pds[ i ] := 1 od;
|
||||
for i from 2 to MAX_NUMBER do
|
||||
for j from i + i to MAX_NUMBER by i do pds[ j ] +:= i od;
|
||||
od;
|
||||
# classify the numbers and count each type
|
||||
local aCount, dCount, pCount := 0, 0, 0;
|
||||
for i to MAX_NUMBER do
|
||||
local constant dSum := pds[ i ];
|
||||
if dSum > i then aCount +:= 1
|
||||
elif dSum < i then dCount +:= 1
|
||||
else pCount +:= 1
|
||||
fi
|
||||
od;
|
||||
printf( "Abundant numbers up to %.0m: %8.0m\n", MAX_NUMBER, aCount );
|
||||
printf( "Perfect numbers up to %.0m: %8.0m\n", MAX_NUMBER, pCount );
|
||||
printf( "Deficient numbers up to %.0m: %8.0m\n", MAX_NUMBER, dCount )
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
(do ;;; count abundant, perfect and deficient numbers up to 20 000
|
||||
; construct a table of proper divisor sums
|
||||
(local (max-number pds) (values 20_000 []))
|
||||
(tset pds 1 0)
|
||||
(for [i 2 max-number] (tset pds i 1))
|
||||
(for [i 2 max-number]
|
||||
(for [j (+ i i) max-number i] (tset pds j (+ i (. pds j))))
|
||||
)
|
||||
; classify the numbers and count each type
|
||||
(var (aCount dCount pCount) (values 0 0 0))
|
||||
(for [i 1 max-number]
|
||||
(local dSum (. pds i))
|
||||
(if (> dSum i) (set aCount (+ aCount 1))
|
||||
(< dSum i) (set dCount (+ dCount 1))
|
||||
(set pCount (+ pCount 1))
|
||||
)
|
||||
)
|
||||
(io.write (string.format "Abundant numbers up to %d: %8d\n" max-number aCount))
|
||||
(io.write (string.format "Perfect numbers up to %d: %8d\n" max-number pCount))
|
||||
(io.write (string.format "Deficient numbers up to %d: %8d\n" max-number dCount))
|
||||
)
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
do -- count abundant, perfect and deficient numbers up to 20 000
|
||||
|
||||
local fmt = require( "fmt" ) -- RC Pluto formatting library
|
||||
|
||||
-- construct a table of proper divisor sums
|
||||
local maxNumber <const>, pds <const> = 20_000, {}
|
||||
pds[ 1 ] = 0
|
||||
for i = 2, maxNumber do pds[ i ] = 1 end
|
||||
for i = 2, maxNumber do
|
||||
for j = i + i, maxNumber, i do pds[ j ] += i end
|
||||
end
|
||||
|
||||
-- classify the numbers and count each type
|
||||
local aCount, dCount, pCount = 0, 0, 0
|
||||
for i = 1, maxNumber do
|
||||
local dSum <const> = pds[ i ]
|
||||
if dSum > i then aCount += 1
|
||||
elseif dSum < i then dCount += 1
|
||||
else pCount += 1
|
||||
end
|
||||
end
|
||||
local formattedMax <const> = string.formatint( maxNumber )
|
||||
fmt.write( "Abundant numbers up to %s: %8s\n", formattedMax, string.formatint( aCount ) )
|
||||
fmt.write( "Perfect numbers up to %s: %8s\n", formattedMax, string.formatint( pCount ) )
|
||||
fmt.write( "Deficient numbers up to %s: %8s\n", formattedMax, string.formatint( dCount ) )
|
||||
end
|
||||
|
|
@ -3,18 +3,19 @@ proper_divisors(N, [1|L]) :-
|
|||
FSQRTN is floor(sqrt(N)),
|
||||
proper_divisors(2, FSQRTN, N, L).
|
||||
|
||||
proper_divisors(M, FSQRTN, _, []) :-
|
||||
M > FSQRTN,
|
||||
!.
|
||||
proper_divisors(M, FSQRTN, N, L) :-
|
||||
N mod M =:= 0, !,
|
||||
MO is N//M, % must be integer
|
||||
L = [M,MO|L1], % both proper divisors
|
||||
M1 is M+1,
|
||||
proper_divisors(M1, FSQRTN, N, L1).
|
||||
proper_divisors(M, FSQRTN, N, L) :-
|
||||
M1 is M+1,
|
||||
proper_divisors(M1, FSQRTN, N, L).
|
||||
proper_divisors(M, FSQRTN, N, [MS|L]) :-
|
||||
between(M, FSQRTN, D1),
|
||||
N mod D1 =:= 0, !,
|
||||
D2 is N//D1, % must be integer
|
||||
( D1 < D2
|
||||
->
|
||||
MS is D1 + D2, % already sum here
|
||||
M2 is D1 + 1,
|
||||
proper_divisors(M2, FSQRTN, N, L)
|
||||
;
|
||||
MS is D1, L = [] % D1 only once
|
||||
).
|
||||
proper_divisors(_, _FSQRTN, _, []) :- !.
|
||||
|
||||
dpa(1, [1], [], []) :-
|
||||
!.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
BEGIN
|
||||
# find some abundant odd numbers - numbers where the sum of the proper #
|
||||
# divisors is bigger than the number #
|
||||
# itself #
|
||||
BEGIN # find some abundant odd numbers - numbers wose the proper divisor sum #
|
||||
# is bigger than the number itself #
|
||||
|
||||
# returns the sum of the proper divisors of n #
|
||||
PROC divisor sum = ( INT n )INT:
|
||||
|
|
@ -41,34 +39,20 @@ BEGIN
|
|||
# 1000th odd abundant number #
|
||||
WHILE a count < 1 000 DO
|
||||
IF ( d sum := divisor sum( odd number ) ) > odd number THEN
|
||||
a count := a count + 1
|
||||
a count +:= 1
|
||||
FI;
|
||||
odd number +:= 2
|
||||
OD;
|
||||
print( ( "1000th abundant odd number:"
|
||||
, newline
|
||||
, " "
|
||||
, whole( odd number - 2, 0 )
|
||||
, " proper divisor sum: "
|
||||
, whole( d sum, 0 )
|
||||
, newline
|
||||
)
|
||||
);
|
||||
print( ( "1000th abundant odd number:", newline, " " ) );
|
||||
print( ( whole( odd number - 2, 0 ), " proper divisor sum: ", whole( d sum, 0 ), newline ) );
|
||||
# first odd abundant number > one billion #
|
||||
odd number := 1 000 000 001;
|
||||
BOOL found := FALSE;
|
||||
WHILE NOT found DO
|
||||
IF ( d sum := divisor sum( odd number ) ) > odd number THEN
|
||||
found := TRUE;
|
||||
print( ( "First abundant odd number > 1 000 000 000:"
|
||||
, newline
|
||||
, " "
|
||||
, whole( odd number, 0 )
|
||||
, " proper divisor sum: "
|
||||
, whole( d sum, 0 )
|
||||
, newline
|
||||
)
|
||||
)
|
||||
print( ( "First abundant odd number > 1 000 000 000:", newline, " " ) );
|
||||
print( ( whole( odd number, 0 ), " proper divisor sum: ", whole( d sum, 0 ), newline ) )
|
||||
FI;
|
||||
odd number +:= 2
|
||||
OD
|
||||
|
|
|
|||
52
Task/Abundant-odd-numbers/Agena/abundant-odd-numbers.agena
Normal file
52
Task/Abundant-odd-numbers/Agena/abundant-odd-numbers.agena
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
scope # find some abundant snumbers
|
||||
# - numbers whose proper divisor sum is bigger than the number itself
|
||||
|
||||
# returns the sum of the proper divisors of n
|
||||
local constant divisor_sum := proc( n :: number ) :: number is
|
||||
local sum := 1;
|
||||
for d from 2 to entier sqrt( n ) do
|
||||
if n mod d = 0 then
|
||||
sum +:= d;
|
||||
other_d := n \ d;
|
||||
if other_d <> d then
|
||||
sum +:= other_d
|
||||
fi
|
||||
fi
|
||||
od;
|
||||
return sum
|
||||
end;
|
||||
scope # find the numbers required by the task
|
||||
# first 25 odd abundant numbers
|
||||
local odd_number, a_count, d_sum := 1, 0, 0;
|
||||
print( "The first 25 abundant odd numbers:" );
|
||||
while a_count < 25 do
|
||||
d_sum := divisor_sum( odd_number );
|
||||
if d_sum > odd_number then
|
||||
a_count +:= 1;
|
||||
printf( "%6d proper divisor sum: %d\n", odd_number, d_sum );
|
||||
fi;
|
||||
odd_number +:= 2
|
||||
od;
|
||||
# 1000th odd abundant number
|
||||
while a_count < 1_000 do
|
||||
d_sum := divisor_sum( odd_number );
|
||||
if d_sum > odd_number then
|
||||
a_count +:= 1
|
||||
fi;
|
||||
odd_number +:= 2
|
||||
od;
|
||||
printf( "1000th abundant odd number:\n %d proper divisor sum: %d\n", odd_number, d_sum );
|
||||
# first odd abundant number > one billion
|
||||
odd_number := 1_000_000_001;
|
||||
local found := false;
|
||||
while not found do
|
||||
d_sum := divisor_sum( odd_number );
|
||||
if d_sum > odd_number then
|
||||
found := true;
|
||||
print( "First abundant odd_number > 1 000 000 000:" );
|
||||
printf( " %d proper divisor sum: %d\n", odd_number, d_sum );
|
||||
fi;
|
||||
odd_number +:= 2
|
||||
od
|
||||
end
|
||||
end
|
||||
35
Task/Abundant-odd-numbers/Pluto/abundant-odd-numbers.pluto
Normal file
35
Task/Abundant-odd-numbers/Pluto/abundant-odd-numbers.pluto
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
local int = require "int"
|
||||
local fmt = require "fmt"
|
||||
require "table2"
|
||||
|
||||
local function abundant_odd(search_from, count_from, count_to, print_one)
|
||||
local count = count_from
|
||||
local n = search_from
|
||||
while count < count_to do
|
||||
local divs = int.divisors(n, true)
|
||||
local tot = #divs > 0 ? (divs:sum()) : 0
|
||||
if tot > n then
|
||||
++count
|
||||
if !print_one or count >= count_to then
|
||||
local s = fmt.swrite(divs, " + ", "")
|
||||
if !print_one then
|
||||
fmt.print("%2d. %5d < %s = %d", count, n, s, tot)
|
||||
else
|
||||
fmt.print("%d < %s = %d", n, s, tot)
|
||||
end
|
||||
end
|
||||
end
|
||||
n += 2
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
local MAX <const> = 25
|
||||
print($"The first {MAX} abundant odd numbers are:")
|
||||
local n = abundant_odd(1, 0, 25, false)
|
||||
|
||||
print("\nThe one thousandth abundant odd number is:")
|
||||
abundant_odd(n, 25, 1000, true)
|
||||
|
||||
print("\nThe first abundant odd number above one billion is:")
|
||||
abundant_odd(1e9 + 1, 0, 1, true)
|
||||
|
|
@ -6,3 +6,6 @@ make-acc-gen: func [start-val] [
|
|||
]
|
||||
]
|
||||
]
|
||||
gen: make-acc-gen 1
|
||||
print gen 5 ;== 6
|
||||
print gen 2.3 ;== 8.3
|
||||
25
Task/Accumulator-factory/REBOL/accumulator-factory-2.rebol
Normal file
25
Task/Accumulator-factory/REBOL/accumulator-factory-2.rebol
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
;; Define a generator function 'gen' with an optional refinement '/init'
|
||||
;; - 'value' is a required number passed to the function
|
||||
;; - '/init' is an optional refinement for initialization
|
||||
gen: function/with [value [number!] /init] [
|
||||
|
||||
;; If '/init' refinement is used, initialize state and exit immediately
|
||||
if init [
|
||||
state: value ;; Set the initial state to the provided value
|
||||
exit ;; Exit, so nothing else in the function is run
|
||||
]
|
||||
|
||||
;; If not initializing, add 'value' to 'state'
|
||||
state: state + value
|
||||
|
||||
;; The function returns the new state each call
|
||||
][state: 0] ;; 'state' is a local variable, initialized once per definition (persistent closure)
|
||||
|
||||
;; Initialize the 'state' value of gen to 1 by calling it with '/init'
|
||||
gen/init 1
|
||||
|
||||
;; Call gen with 5: Adds 5 to state and prints the result (should print 6)
|
||||
print gen 5
|
||||
|
||||
;; Call gen with 2.3: Adds 2.3 to state and prints the result (should print 8.3)
|
||||
print gen 2.3
|
||||
63
Task/Achilles-numbers/Pluto/achilles-numbers.pluto
Normal file
63
Task/Achilles-numbers/Pluto/achilles-numbers.pluto
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
local int = require "int"
|
||||
local fmt = require "fmt"
|
||||
|
||||
$define MAX_DIGITS = 15
|
||||
|
||||
local pps = {}
|
||||
|
||||
local function get_perfect_powers(max_exp)
|
||||
local upper = 10 ^ max_exp
|
||||
for i = 2.0, int.sqrt(upper) do
|
||||
local p = i
|
||||
while true do
|
||||
p *= i
|
||||
if p >= upper then break end
|
||||
pps[p] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_achilles(min_exp, max_exp)
|
||||
local lower = 10 ^ min_exp
|
||||
local upper = 10 ^ max_exp
|
||||
local achilles = {} -- avoids duplicates
|
||||
for b = 1.0, int.cbrt(upper) do
|
||||
local b3 = b * b * b
|
||||
for a = 1.0, int.sqrt(upper) do
|
||||
local p = b3 * a * a
|
||||
if p >= upper then break end
|
||||
if p >= lower then
|
||||
if !pps[p] then achilles[p] = true end
|
||||
end
|
||||
end
|
||||
end
|
||||
return achilles
|
||||
end
|
||||
|
||||
get_perfect_powers(MAX_DIGITS)
|
||||
local achilles_set = get_achilles(1, 5) -- enough for first 2 parts
|
||||
local achilles = achilles_set:keys()
|
||||
achilles:sort()
|
||||
|
||||
print("First 50 Achilles numbers:")
|
||||
fmt.tprint("%4d", achilles:slice(1, 50), 10)
|
||||
|
||||
print("\nFirst 30 strong Achilles numbers:")
|
||||
local strong_achilles = {}
|
||||
local count = 0
|
||||
local n = 1
|
||||
while count < 30 do
|
||||
local tot = int.totient(achilles[n])
|
||||
if achilles_set[tot] then
|
||||
strong_achilles:insert(achilles[n])
|
||||
++count
|
||||
end
|
||||
++n
|
||||
end
|
||||
fmt.tprint("%5d", strong_achilles, 10)
|
||||
|
||||
print("\nNumber of Achilles numbers with:")
|
||||
for d = 2, MAX_DIGITS do
|
||||
local ac = get_achilles(d - 1, d):size()
|
||||
fmt.print("%2d digits: %d", d, ac)
|
||||
end
|
||||
8
Task/Ackermann-function/ArkScript/ackermann-function.ark
Normal file
8
Task/Ackermann-function/ArkScript/ackermann-function.ark
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
(let ackermann (fun (m n) {
|
||||
(if (> m 0)
|
||||
(if (= 0 n)
|
||||
(ackermann (- m 1) 1)
|
||||
(ackermann (- m 1) (ackermann m (- n 1))))
|
||||
(+ 1 n)) }))
|
||||
|
||||
(assert (= 509 (ackermann 3 6)) "(ackermann 3 6) == 509")
|
||||
13
Task/Ackermann-function/Pluto/ackermann-function.pluto
Normal file
13
Task/Ackermann-function/Pluto/ackermann-function.pluto
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
function ack(m,n)
|
||||
if m==0 then
|
||||
return n+1
|
||||
elseif n == 0 then
|
||||
return ack(m-1,1)
|
||||
else return ack(m-1,ack(m,n-1)) end
|
||||
end
|
||||
|
||||
for i = 0,3 do
|
||||
for j = 0,8 do
|
||||
print($"A({i},{j})={ack(i,j)}")
|
||||
end
|
||||
end
|
||||
7
Task/Ackermann-function/REBOL/ackermann-function-1.rebol
Normal file
7
Task/Ackermann-function/REBOL/ackermann-function-1.rebol
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
ackermann: func [m n] [
|
||||
case [
|
||||
m = 0 [n + 1]
|
||||
n = 0 [ackermann m - 1 1]
|
||||
true [ackermann m - 1 ackermann m n - 1]
|
||||
]
|
||||
]
|
||||
16
Task/Ackermann-function/REBOL/ackermann-function-2.rebol
Normal file
16
Task/Ackermann-function/REBOL/ackermann-function-2.rebol
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
ackermann: func [
|
||||
m [integer!]
|
||||
n [integer!]
|
||||
] [
|
||||
;; Small-m closed forms
|
||||
case [
|
||||
m = 0 [n + 1]
|
||||
m = 1 [n + 2]
|
||||
m = 2 [(2 * n) + 3]
|
||||
m = 3 [
|
||||
;; 2^(n+3) - 3
|
||||
(to integer! power 2 (n + 3)) - 3
|
||||
]
|
||||
;; m >= 4 causes stack overflow
|
||||
]
|
||||
]
|
||||
11
Task/Ackermann-function/TAV/ackermann-function.tav
Normal file
11
Task/Ackermann-function/TAV/ackermann-function.tav
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
ackermann (n) (m) :
|
||||
? n = 0
|
||||
:> m+1
|
||||
? m = 0
|
||||
:> ackermann (n-1) 1
|
||||
:> ackermann (n-1) ackermann n (m-1) \ = ackermann (n-1) (ackermann n (m-1))
|
||||
\ test it
|
||||
main(params):+
|
||||
p1 =: string params[1] as integer else 3
|
||||
p2 =: string params[2] as integer else 5
|
||||
print "ackermann(" _ p1 _ "," _ p2 _ ") = " _ ackermann p1 p2
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
local s = ""
|
||||
local t = {}
|
||||
local function f() end
|
||||
local n = 1
|
||||
local b = true
|
||||
print(string.format("%p\t%p\t%p\t%p\t%p", s, t, f, n, b))
|
||||
|
|
@ -1 +1,18 @@
|
|||
zzz = storage(xxx)
|
||||
-- 7 Aug 2025
|
||||
include Settings
|
||||
|
||||
say 'ADDRESS OF A VARIABLE'
|
||||
say version
|
||||
say
|
||||
if Pos('Regina',version) > 0 then
|
||||
call Library
|
||||
call Primes 10
|
||||
call SysDumpVariables
|
||||
exit
|
||||
|
||||
Library:
|
||||
call RxFuncAdd 'SysLoadFuncs','RegUtil','SysLoadFuncs'
|
||||
call SysLoadFuncs
|
||||
return
|
||||
|
||||
include Math
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
# riscv assembly raspberry pico2 rp2350
|
||||
# program adrvariable.s
|
||||
# connexion putty com3
|
||||
/*********************************************/
|
||||
/* CONSTANTES */
|
||||
/********************************************/
|
||||
/* for this file see risc-v task include a file */
|
||||
.include "../../constantesRiscv.inc"
|
||||
|
||||
/*******************************************/
|
||||
/* INITIALED DATAS */
|
||||
/*******************************************/
|
||||
.data
|
||||
szMessStart: .asciz "Program riscv start.\r\n"
|
||||
szCariageReturn: .asciz "\r\n"
|
||||
.align 2
|
||||
tabValues: .int 1,2,3,4
|
||||
|
||||
/*******************************************/
|
||||
/* UNINITIALED DATA */
|
||||
/*******************************************/
|
||||
.bss
|
||||
.align 2
|
||||
sConvArea: .skip 24
|
||||
ivalue1: .skip 4
|
||||
|
||||
/**********************************************/
|
||||
/* SECTION CODE */
|
||||
/**********************************************/
|
||||
.text
|
||||
.global main
|
||||
|
||||
main:
|
||||
call stdio_init_all # général init
|
||||
1: # start loop connexion
|
||||
li a0,0 # raz argument register
|
||||
call tud_cdc_n_connected # waiting for USB connection
|
||||
beqz a0,1b # return code = zero ?
|
||||
|
||||
la a0,szMessStart # message address
|
||||
call writeString # display message
|
||||
|
||||
la t1,ivalue1 # variable address
|
||||
lw a0,(t1) # load word value
|
||||
call displayResult
|
||||
la t1,ivalue1 # variable address
|
||||
li t0,12345 # new value
|
||||
sw t0,(t1) # store word value
|
||||
la t1,ivalue1 # variable address
|
||||
lw a0,(t1) # load value for control
|
||||
call displayResult
|
||||
la t1,tabValues # load array address
|
||||
lw a0,8(t1) # load value at byte 8 of array
|
||||
call displayResult
|
||||
la t1,tabValues # load array address
|
||||
li t2,3 # init index value
|
||||
slli t2,t2,2 # multiply index by 5 (integer size)
|
||||
add t2,t2,t1 # add offset to array address
|
||||
lw a0,(t2) # load value of index
|
||||
call displayResult
|
||||
|
||||
call getchar
|
||||
100: # final loop
|
||||
j 100b
|
||||
|
||||
/**********************************************/
|
||||
/* displayResult */
|
||||
/**********************************************/
|
||||
/* a0 value */
|
||||
.equ LGZONECONV, 20
|
||||
displayResult:
|
||||
addi sp, sp, -4 # reserve stack
|
||||
sw ra, 0(sp)
|
||||
la a1,sConvArea # conversion result address
|
||||
call conversion10 # conversion decimal
|
||||
la a0,sConvArea # message address
|
||||
call writeString # display message
|
||||
la a0,szCariageReturn
|
||||
call writeString
|
||||
100:
|
||||
lw ra, 0(sp)
|
||||
addi sp, sp, 4
|
||||
ret
|
||||
|
||||
/**********************************************/
|
||||
/* decimal conversion */
|
||||
/**********************************************/
|
||||
/* a0 value */
|
||||
/* a1 conversion array address */
|
||||
.equ LGZONECONV, 20
|
||||
conversion10:
|
||||
addi sp, sp, -4
|
||||
sw ra, 0(sp)
|
||||
li t1,LGZONECONV
|
||||
li t2,10 # divisor
|
||||
1:
|
||||
rem t4,a0,t2 # division remainder by 10
|
||||
addi t4,t4,48 # convert to decimal
|
||||
add t5,a1,t1 # store character position
|
||||
sb t4,(t5) # store byte
|
||||
div a0,a0,t2 # compute quotient
|
||||
beq a0,x0,2f # compare to 0
|
||||
addi t1,t1,-1 # decrement store position
|
||||
bgt t1,x0,1b # and loop if position is ok
|
||||
2:
|
||||
li t2,0 # raz indice
|
||||
li t3,LGZONECONV
|
||||
3: # loop to transfer result at begining conversion area
|
||||
add t5,a1,t1 # compute start position
|
||||
lb t4,(t5) # load byte
|
||||
add t5,a1,t2 # compute new position
|
||||
sb t4,(t5) # and store byte
|
||||
addi t2,t2,1 # increment indice
|
||||
addi t1,t1,1
|
||||
ble t1,t3,3b # and loop if indice <= area size
|
||||
add t5,a1,t2 # increment final position
|
||||
sb x0,(t5) # and store byte final zero
|
||||
mv a0,t2 # return size conversion
|
||||
|
||||
100:
|
||||
lw ra, 0(sp)
|
||||
addi sp, sp, 4
|
||||
ret
|
||||
/************************************/
|
||||
/* file include Fonctions */
|
||||
/***********************************/
|
||||
/* for this file see risc-v task include a file */
|
||||
.include "../../includeFunctions.s"
|
||||
17
Task/Address-of-a-variable/Red/address-of-a-variable.red
Normal file
17
Task/Address-of-a-variable/Red/address-of-a-variable.red
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
Red/System []
|
||||
|
||||
print ["pointer test:" newline]
|
||||
|
||||
a: 100
|
||||
print ["a is an integer variable, value: " a newline]
|
||||
|
||||
p: declare pointer! [integer!]
|
||||
p: :a
|
||||
print ["p is the address of a: " p newline]
|
||||
print ["p/value refer to the value pointed to by p: " p/value newline]
|
||||
|
||||
q: declare pointer! [integer!]
|
||||
q: p + 1
|
||||
print ["q is p + 1: " q " q/value is (uninitialized): " q/value newline]
|
||||
|
||||
print ["q - p: " (q - p) newline]
|
||||
|
|
@ -27,37 +27,38 @@ make term(text in file, "$");
|
|||
|
||||
on physical file end(text in file, (REF FILE skip)BOOL: stop iteration);
|
||||
on logical file end(text in file, (REF FILE skip)BOOL: stop iteration);
|
||||
BOOL at eol := FALSE;
|
||||
on line end(text in file, (REF FILE skip)BOOL: at eol := TRUE);
|
||||
FOR row DO
|
||||
on line end(text in file, (REF FILE skip)BOOL: stop iteration);
|
||||
FOR col DO
|
||||
STRING tok;
|
||||
at eol := FALSE;
|
||||
FOR col WHILE NOT at eol DO
|
||||
STRING tok := "";
|
||||
getf(text in file, ($gx$,tok));
|
||||
IF row > 1 UPB page THEN page := flex page(page, row, 2 UPB page) FI;
|
||||
IF col > 2 UPB page THEN page := flex page(page, 1 UPB page, col) FI;
|
||||
page[row,col]:=tok
|
||||
OD;
|
||||
stop iteration:
|
||||
SKIP
|
||||
IF tok NE "" OR NOT at eol THEN
|
||||
IF row > 1 UPB page THEN page := flex page(page, row, 2 UPB page) FI;
|
||||
IF col > 2 UPB page THEN page := flex page(page, 1 UPB page, col) FI;
|
||||
page[row,col]:=tok
|
||||
FI
|
||||
OD
|
||||
OD;
|
||||
stop iteration:
|
||||
SKIP;
|
||||
|
||||
BEGIN
|
||||
PROC aligner = (PAGE in page, PROC (STRING,INT)STRING aligner)VOID:(
|
||||
PAGE page := in page;
|
||||
[2 UPB page]INT max width;
|
||||
PROC aligner = (PAGE in page, PROC (STRING,INT)STRING alignf)VOID:(
|
||||
PAGE al page := in page;
|
||||
FOR col TO 2 UPB page DO
|
||||
INT max len:=0; FOR row TO UPB page DO IF UPB page[row,col]>max len THEN max len:=UPB page[row,col] FI OD;
|
||||
FOR row TO UPB page DO page[row,col] := aligner(page[row,col], maxlen) OD
|
||||
INT max len:=0; FOR row TO UPB al page DO IF UPB al page[row,col]>max len THEN max len:=UPB al page[row,col] FI OD;
|
||||
FOR row TO UPB al page DO al page[row,col] := alignf(page[row,col], maxlen) OD
|
||||
OD;
|
||||
printf(($n(UPB page)(n(2 UPB page -1)(gx)gl)$,page))
|
||||
printf(($n(UPB page)(n(2 UPB page -1)(gx)gl)$,al page))
|
||||
);
|
||||
|
||||
PROC left = (STRING in, INT len)STRING: in + " "*(len - UPB in),
|
||||
right = (STRING in, INT len)STRING: " "*(len - UPB in) + in,
|
||||
centre = (STRING in, INT len)STRING: ( INT pad=len-UPB in; pad%2*" "+ in + (pad-pad%2)*" " );
|
||||
|
||||
[]STRUCT(STRING name, PROC(STRING,INT)STRING align) aligners = (("Left",left), ("Left",right), ("Centre",centre));
|
||||
[]STRUCT(STRING name, PROC(STRING,INT)STRING align) aligners = (("Left",left), ("right",right), ("Centre",centre));
|
||||
|
||||
FOR index TO UPB aligners DO
|
||||
print((new line, "# ",name OF aligners[index]," Column-aligned output:",new line));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
// See https://en.wikipedia.org/wiki/Divisor_function
|
||||
function divisorSum(n) {
|
||||
let total = 1n;
|
||||
let power = 2n;
|
||||
// Deal with powers of 2 first
|
||||
for (; n % 2n === 0n; power *= 2n, n /= 2n) {
|
||||
total += power;
|
||||
}
|
||||
// Odd prime factors up to the square root
|
||||
for (let p = 3n; p * p <= n; p += 2n) {
|
||||
let sum = 1n;
|
||||
for (power = p; n % p === 0n; power *= p, n /= p) {
|
||||
sum += power;
|
||||
}
|
||||
total *= sum;
|
||||
}
|
||||
// If n > 1 then it's prime
|
||||
if (n > 1n) {
|
||||
total *= n + 1n;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
// See https://en.wikipedia.org/wiki/Aliquot_sequence
|
||||
function classifyAliquotSequence(n) {
|
||||
const limit = 16;
|
||||
const terms = new Array(limit);
|
||||
terms[0] = n;
|
||||
let classification = "non-terminating";
|
||||
let length = 1;
|
||||
|
||||
for (let i = 1; i < limit; ++i) {
|
||||
++length;
|
||||
terms[i] = divisorSum(terms[i - 1]) - terms[i - 1];
|
||||
|
||||
if (terms[i] === n) {
|
||||
classification =
|
||||
(i === 1 ? "perfect" : (i === 2 ? "amicable" : "sociable"));
|
||||
break;
|
||||
}
|
||||
|
||||
let j = 1;
|
||||
for (; j < i; ++j) {
|
||||
if (terms[i] === terms[i - j]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j < i) {
|
||||
classification = (j === 1 ? "aspiring" : "cyclic");
|
||||
break;
|
||||
}
|
||||
|
||||
if (terms[i] === 0n) {
|
||||
classification = "terminating";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let output = `${n}: ${classification}, sequence: ${terms[0]}`;
|
||||
for (let i = 1; i < length && terms[i] !== terms[i - 1]; ++i) {
|
||||
output += ` ${terms[i]}`;
|
||||
}
|
||||
console.log(output);
|
||||
}
|
||||
|
||||
function main() {
|
||||
for (let i = 1n; i <= 10n; ++i) {
|
||||
classifyAliquotSequence(i);
|
||||
}
|
||||
|
||||
const specialNumbers = [11n, 12n, 28n, 496n, 220n, 1184n, 12496n, 1264460n, 790n, 909n, 562n, 1064n, 1488n];
|
||||
for (const i of specialNumbers) {
|
||||
classifyAliquotSequence(i);
|
||||
}
|
||||
|
||||
classifyAliquotSequence(15355717786080n);
|
||||
classifyAliquotSequence(153557177860800n);
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
-- Big_Reals is an Ada 2022 unit
|
||||
with Ada.Numerics.Big_Numbers.Big_Reals;
|
||||
with Ada.Text_IO;
|
||||
|
||||
use Ada.Numerics.Big_Numbers.Big_Reals;
|
||||
|
||||
procedure Almkvist_Giullera is
|
||||
|
||||
function "+" (B : Big_Real; A : Integer) return Big_Real is (B + To_Real (A));
|
||||
function "*" (A : Integer; B : Big_Real) return Big_Real is (To_Real (A) * B);
|
||||
B0 : constant Big_Real := To_Real (0);
|
||||
B1 : constant Big_Real := B0 + 1;
|
||||
|
||||
function Factorial (N : Big_Real) return Big_Real
|
||||
is
|
||||
I : Big_Real := N;
|
||||
F : Big_Real := B1;
|
||||
begin
|
||||
while I > B1 loop
|
||||
F := F * I;
|
||||
I := I - B1;
|
||||
end loop;
|
||||
|
||||
return F;
|
||||
end Factorial;
|
||||
|
||||
function F (N : Big_Real) return Big_Real renames Factorial;
|
||||
procedure Put_Line (S : String) renames Ada.Text_IO.Put_Line;
|
||||
|
||||
function Integer_Term (N : Big_Real) return Big_Real is
|
||||
(32 * F (6 * N) / (3 * F (N) ** 6) * (532 * N ** 2 + 126 * N + 9));
|
||||
|
||||
procedure Show_Integer_Terms (N : Positive) is
|
||||
begin
|
||||
for I in 0 .. N - 1 loop
|
||||
Put_Line ("Almkvist-Giullera integer term "
|
||||
& I'Image & " is "
|
||||
& To_String (Integer_Term (To_Real (I)), Aft => 0));
|
||||
end loop;
|
||||
end Show_Integer_Terms;
|
||||
|
||||
-- Use Newton's Method
|
||||
function Sqrt (N : Big_Real; Precision : Positive) return Big_Real is
|
||||
Diff : Big_Real := To_Real (10) ** (-Precision);
|
||||
Estimate : Big_Real := B0;
|
||||
Next : Big_Real := N;
|
||||
begin
|
||||
while abs (Next - Estimate) > Diff loop
|
||||
Estimate := Next;
|
||||
Next := Estimate - (Estimate ** 2 - N) / (2 * Estimate);
|
||||
-- Nasty hack to limit precision. Otherwise there is a storage error.
|
||||
Next := From_String (To_String (Next, Aft => Precision + 2));
|
||||
end loop;
|
||||
|
||||
return Estimate;
|
||||
end Sqrt;
|
||||
|
||||
function Estimate_Pi (N : Integer; Precision : Positive) return Big_Real is
|
||||
Sum : Big_Real := B0;
|
||||
begin
|
||||
for I in 0 .. N loop
|
||||
Sum := Sum + Integer_Term (To_Real (I)) / To_Real (10) ** (6 * I + 3);
|
||||
Sum := From_String (To_String (Sum, Aft => Precision + 2));
|
||||
end loop;
|
||||
|
||||
return B1 / Sqrt (Sum, Precision + 2);
|
||||
end Estimate_Pi;
|
||||
|
||||
function Compute_Pi (Precision : Positive) return Big_Real is
|
||||
Diff : constant Big_Real := To_Real (10) ** (-Precision);
|
||||
Pi_Estimate : Big_Real := B0;
|
||||
Next : Big_Real := B1;
|
||||
N : Integer := 1;
|
||||
begin
|
||||
while abs (Next - Pi_Estimate) > Diff loop
|
||||
N := N * 2;
|
||||
Pi_Estimate := Next;
|
||||
Next := Estimate_Pi (N, Precision);
|
||||
end loop;
|
||||
|
||||
return Pi_Estimate;
|
||||
end Compute_Pi;
|
||||
|
||||
procedure Show_Pi (Precision : Positive) is
|
||||
Pi : constant Big_Real := Compute_Pi (Precision);
|
||||
begin
|
||||
Put_Line ("Pi to " & Precision'Image & " places is "
|
||||
& To_String (Pi, Aft => Precision));
|
||||
end Show_Pi;
|
||||
|
||||
begin
|
||||
Show_Integer_Terms (10);
|
||||
Show_Pi (70);
|
||||
end almkvist_giullera;
|
||||
|
|
@ -6,5 +6,5 @@ procedure main()
|
|||
end
|
||||
|
||||
procedure genKap(k)
|
||||
suspend (k = *factors(n := seq(q)), n)
|
||||
suspend (k = *factors(n := seq()), n)
|
||||
end
|
||||
|
|
|
|||
26
Task/Almost-prime/Pluto/almost-prime.pluto
Normal file
26
Task/Almost-prime/Pluto/almost-prime.pluto
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
local function k_prime(n, k)
|
||||
local nf = 0
|
||||
for i = 2, n do
|
||||
while n % i == 0 do
|
||||
if nf == k then return false end
|
||||
++nf
|
||||
n //= i
|
||||
end
|
||||
end
|
||||
return nf == k
|
||||
end
|
||||
|
||||
local function gen(k, n)
|
||||
local r = {}
|
||||
local m = 2
|
||||
for i = 1, n do
|
||||
while !k_prime(m, k) do ++m end
|
||||
r[i] = m
|
||||
++m
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
for k = 1, 5 do
|
||||
print($"{k}: {gen(k, 10):concat(", ")}")
|
||||
end
|
||||
78
Task/Amb/Ada/amb-2.ada
Normal file
78
Task/Amb/Ada/amb-2.ada
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
-- MacOS, GNAT, gnat-aarch64-darwin-15.1.0-2
|
||||
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
|
||||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
|
||||
procedure Test_Amb is
|
||||
type Alternatives is array (Positive range <>) of Unbounded_String;
|
||||
|
||||
type Amb (Count : Positive) is record
|
||||
This : Positive := 1;
|
||||
Left : access Amb;
|
||||
List : Alternatives (1..Count);
|
||||
end record;
|
||||
|
||||
function "/" (L, R : String) return Amb;
|
||||
function "/" (L : Amb; R : String) return Amb;
|
||||
function "=" (L, R : Amb) return Boolean;
|
||||
function Image (L : Amb) return String;
|
||||
procedure Join (L : access Amb; R : in out Amb);
|
||||
procedure Failure (L : in out Amb);
|
||||
|
||||
function Image (L : Amb) return String is
|
||||
begin
|
||||
return To_String (L.List (L.This));
|
||||
end Image;
|
||||
|
||||
function "/" (L, R : String) return Amb is
|
||||
Result : Amb (2);
|
||||
begin
|
||||
Append (Result.List (1), L);
|
||||
Append (Result.List (2), R);
|
||||
return Result;
|
||||
end "/";
|
||||
|
||||
function "/" (L : Amb; R : String) return Amb is
|
||||
Result : Amb (L.Count + 1);
|
||||
begin
|
||||
Result.List (1..L.Count) := L.List ;
|
||||
Append (Result.List (Result.Count), R);
|
||||
return Result;
|
||||
end "/";
|
||||
|
||||
function "=" (L, R : Amb) return Boolean is
|
||||
Left : Unbounded_String renames L.List (L.This);
|
||||
begin
|
||||
return Element (Left, Length (Left)) = Element (R.List (R.This), 1);
|
||||
end "=";
|
||||
|
||||
procedure Failure (L : in out Amb) is
|
||||
begin
|
||||
loop
|
||||
if L.This < L.Count then
|
||||
L.This := L.This + 1;
|
||||
else
|
||||
L.This := 1;
|
||||
Failure (L.Left.all);
|
||||
end if;
|
||||
exit when L.Left = null or else L.Left.all = L;
|
||||
end loop;
|
||||
end Failure;
|
||||
|
||||
procedure Join (L : access Amb; R : in out Amb) is
|
||||
begin
|
||||
R.Left := L;
|
||||
while L.all /= R loop
|
||||
Failure (R);
|
||||
end loop;
|
||||
end Join;
|
||||
|
||||
W_1 : aliased Amb := "the" / "that" / "a";
|
||||
W_2 : aliased Amb := "frog" / "elephant" / "thing";
|
||||
W_3 : aliased Amb := "walked" / "treaded" / "grows";
|
||||
W_4 : aliased Amb := "slowly" / "quickly";
|
||||
begin
|
||||
Join (W_1'Access, W_2);
|
||||
Join (W_2'Access, W_3);
|
||||
Join (W_3'Access, W_4);
|
||||
Put_Line (Image (W_1) & ' ' & Image (W_2) & ' ' & Image (W_3) & ' ' & Image (W_4));
|
||||
end Test_Amb;
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
amicable: procedure options (main);
|
||||
|
||||
%replace
|
||||
search_limit by 20000;
|
||||
|
||||
dcl (a, b, found) fixed bin;
|
||||
|
||||
put skip list ('Searching for amicable pairs up to ');
|
||||
put edit (search_limit) (f(5));
|
||||
found = 0;
|
||||
do a = 2 to search_limit;
|
||||
b = sumf(a);
|
||||
if (b > a) then
|
||||
do;
|
||||
if (sumf(b) = a) then
|
||||
do;
|
||||
found = found + 1;
|
||||
put skip edit (a,b) (f(7));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
put skip list (found, ' pairs were found');
|
||||
stop;
|
||||
|
||||
|
||||
/* return sum of the proper divisors of n */
|
||||
sumf:
|
||||
procedure(n) returns (fixed bin);
|
||||
|
||||
dcl (n, sum, f1, f2) fixed bin;
|
||||
|
||||
sum = 1; /* 1 is a proper divisor of every number */
|
||||
f1 = 2;
|
||||
do while ((f1 * f1) < n);
|
||||
if mod(n, f1) = 0 then
|
||||
do;
|
||||
sum = sum + f1;
|
||||
f2 = n / f1;
|
||||
/* don't double count identical co-factors! */
|
||||
if f2 > f1 then sum = sum + f2;
|
||||
end;
|
||||
f1 = f1 + 1;
|
||||
end;
|
||||
return (sum);
|
||||
end sumf;
|
||||
|
||||
end amicable;
|
||||
|
|
@ -3,7 +3,7 @@ amicable: procedure options (main);
|
|||
%replace
|
||||
search_limit by 20000;
|
||||
|
||||
dcl sumf( 1 : search_limit ) fixed bin;
|
||||
dcl sumf(1 : search_limit) fixed bin;
|
||||
dcl (a, b, found) fixed bin;
|
||||
|
||||
put skip list ('Searching for amicable pairs up to ');
|
||||
|
|
@ -12,7 +12,7 @@ amicable: procedure options (main);
|
|||
do a = 1 to search_limit; sumf( a ) = 1; end;
|
||||
do a = 2 to search_limit;
|
||||
do b = a + a to search_limit by a;
|
||||
sumf( b ) = sumf( b ) + a;
|
||||
sumf(b) = sumf(b) + a;
|
||||
end;
|
||||
end;
|
||||
|
||||
20
Task/Anagrams/DuckDB/anagrams.duckdb
Normal file
20
Task/Anagrams/DuckDB/anagrams.duckdb
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# The MAP giving the frequency counts of characters in the given string
|
||||
create or replace function spectrum(str) as (
|
||||
select histogram(c)
|
||||
from (select unnest(regexp_extract_all(str,'.')) as c)
|
||||
);
|
||||
|
||||
# Find the anagram groups having the most members.
|
||||
# Each group is sorted, and the groups are sorted by first word in the group.
|
||||
with words as (from read_csv('unixdict.txt', header=false) _(word)),
|
||||
histograms as (select word, spectrum(word) as h from words),
|
||||
groups as (select h, count(h) as c from histograms group by h order by c desc),
|
||||
mx as (select max(c) as mx from groups),
|
||||
maximals as (select h from groups, mx where c = mx.mx),
|
||||
results as (select (select array_agg(word).list_sort()
|
||||
from histograms
|
||||
where histograms.h = maximals.h ) as anagrams
|
||||
from maximals)
|
||||
select anagrams
|
||||
from results
|
||||
order by anagrams[1] ;
|
||||
38
Task/Anagrams/TAV/anagrams.tav
Normal file
38
Task/Anagrams/TAV/anagrams.tav
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
\( Find anagrams (words with the same set of letters)
|
||||
Words are the lines of an input file.
|
||||
Sorting the letters of the word gives the key for a map
|
||||
having a list (row) of all words so far.
|
||||
\)
|
||||
\+ stdlib
|
||||
main(parms):+
|
||||
parms[1] =~ 'unixdict.txt' \ default input file
|
||||
wordmap =: get words from parms[1]
|
||||
maxw =: wordmap.maxlen
|
||||
?# idx =: map wordmap give keys ascending
|
||||
words =: wordmap{idx}
|
||||
? maxw = words.count
|
||||
print words::join values by ', '
|
||||
|
||||
\ read the file (infn) and return a map
|
||||
get words from (infn):
|
||||
res =: new map \ create the result map
|
||||
res.maxlen =: 0
|
||||
?# line =: file infn give lines \ or: infn::give lines
|
||||
add line to res
|
||||
:> res
|
||||
|
||||
\ add a word to the map
|
||||
add (word) to (amap):
|
||||
idx =: sort characters of word::case to upper
|
||||
row =: amap{idx} \ get indexed words
|
||||
? row = () \ new entry if void
|
||||
row =: new row
|
||||
amap{idx} =: row
|
||||
row[] =: word \ add new entry
|
||||
amap.maxlen =: maximum of amap.maxlen, row.count
|
||||
|
||||
\ Sort the characters of a string
|
||||
sort characters of (s):
|
||||
sr =: string s as character row
|
||||
row sr sort ascending
|
||||
:> row sr join values as string \ without separator
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
test_angles <- c(-2,-1,0,1,2,6.2831853,16,57.2957795,359,399,6399,1000000)
|
||||
|
||||
d2d <- function(a) sign(a)*(abs(a)%%360)
|
||||
g2g <- function(a) sign(a)*(abs(a)%%400)
|
||||
m2m <- function(a) sign(a)*(abs(a)%%6400)
|
||||
r2r <- function(a) sign(a)*(abs(a)%%(2*pi))
|
||||
|
||||
normalised <- as.data.frame(sapply(c(d2d,g2g,m2m,r2r), function(f) f(test_angles)))
|
||||
unitnames <- c("deg","grad","mil","rad")
|
||||
colnames(normalised) <- sapply(unitnames, function(s) paste0(s, "_norm"))
|
||||
|
||||
d2x <- function(a, unit) switch(unit, "grad"=a*10/9, "mil"=a*160/9, "rad"=a*pi/180)
|
||||
g2x <- function(a, unit) switch(unit, "deg"=a*9/10, "mil"=a*16, "rad"=a*pi/200)
|
||||
m2x <- function(a, unit) switch(unit, "deg"=a*9/160, "grad"=a/16, "rad"=a*pi/3200)
|
||||
r2x <- function(a, unit) switch(unit, "deg"=a*180/pi, "grad"=a*200/pi, "mil"=a*3200/pi)
|
||||
|
||||
deg_conv <- sapply(unitnames[-1], function(unit) d2x(d2d(test_angles), unit))
|
||||
grad_conv <- sapply(unitnames[-2], function(unit) g2x(g2g(test_angles), unit))
|
||||
mil_conv <- sapply(unitnames[-3], function(unit) m2x(m2m(test_angles), unit))
|
||||
rad_conv <- sapply(unitnames[-4], function(unit) r2x(r2r(test_angles), unit))
|
||||
|
||||
conv_list <- list(deg_conv, grad_conv, mil_conv, rad_conv)
|
||||
setNames(lapply(1:4, function(n) cbind(test_angles, normalised[n], conv_list[[n]])), unitnames)
|
||||
11
Task/Anonymous-recursion/DuckDB/anonymous-recursion.duckdb
Normal file
11
Task/Anonymous-recursion/DuckDB/anonymous-recursion.duckdb
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
create or replace function fib(n) as (
|
||||
if ( n < 0, error('negative arguments not allowed'),
|
||||
(with recursive fib(i,e,f) as (
|
||||
select 1, 1, 1
|
||||
union all
|
||||
select i+1, e+f, e from fib
|
||||
where i <= n)
|
||||
select last(f order by i)
|
||||
from fib)
|
||||
)
|
||||
);
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue