Data update

This commit is contained in:
Ingy döt Net 2025-08-11 18:05:26 -07:00
parent 4d5544505c
commit 4924dd0264
3073 changed files with 55820 additions and 4408 deletions

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -0,0 +1,16 @@
двери = новый-массив 100 ложь
цикл
шаг
в-диапазоне 1 101
цикл
номер
в-диапазоне (шаг - 1) 100 шаг
двери[номер] := не двери[номер]
цикл
номер 100
вывести/перенос
формат «Дверь ~a ~a»
номер + 1
двери[номер] ? «открыта» «закрыта»

View 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"

View 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))))

View 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]

View 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)

View file

@ -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.

View 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;

View file

@ -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]

View file

@ -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..]]

View file

@ -0,0 +1 @@
run n = takeWhile (< n) [k*k | k <- [1..]]

View file

@ -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

View file

@ -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

View file

@ -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"]
]
]

View 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"]
]

View 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).

View file

@ -0,0 +1,3 @@
// Игра в 15 PABCWork.NET\Samples\Games\15.pas
see
https://rosettacode.org/wiki/15_puzzle_game#PascalABC.NET

View file

@ -142,7 +142,7 @@ proc handle_mup .
on mouse_up
handle_mup
.
on key
on key_down
if stat = 2
if keybkey = " " : init
return

View 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});
}

View file

@ -1,4 +1,4 @@
include resources "24 Game Icon.icns"
//include resources "24 Game Icon.icns"
#build CompilerOptions @"-Wno-unused-variable"

View file

@ -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");
}
}

View file

@ -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

View file

@ -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

View 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);
}
}

View 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)) })

View 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)) ;

View 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 ;

View 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

View 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.")

View file

@ -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

View 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)))))

View 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') );

View 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
View 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
View file

@ -0,0 +1,2 @@
a, b = io.read("*n", "*n")
print(a+b)

6
Task/A+B/TAV/a+b.tav Normal file
View 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

View 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);

View 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

View file

@ -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

View 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

View 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 ""

View file

@ -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

View 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.

View 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;
?>

View 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

View 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

View file

@ -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

View 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

View 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

View file

@ -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];

View 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();
}

View 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 inorder.
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
}
/// Recomputes 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

View 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();
}

View 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")

View 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.

View file

@ -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.

View file

@ -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))

View file

@ -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],
});
}

View file

@ -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)

View file

@ -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

View 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);
}

View 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.

View 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.

View 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());
}
}
}

View 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()

View file

@ -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

View file

@ -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

View file

@ -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))
)

View file

@ -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

View file

@ -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], [], []) :-
!.

View file

@ -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

View 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

View 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)

View file

@ -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

View 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

View 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

View 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")

View 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

View 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]
]
]

View 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
]
]

View 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

View file

@ -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))

View file

@ -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

View file

@ -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"

View 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]

View file

@ -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));

View file

@ -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();

View file

@ -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;

View file

@ -6,5 +6,5 @@ procedure main()
end
procedure genKap(k)
suspend (k = *factors(n := seq(q)), n)
suspend (k = *factors(n := seq()), n)
end

View 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
View 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;

View file

@ -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;

View file

@ -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;

View 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] ;

View 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

View file

@ -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)

View 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