Data update

This commit is contained in:
Ingy döt Net 2024-07-13 15:19:22 -07:00
parent 29a5eea0d4
commit 5c1bb7bfa9
2011 changed files with 35081 additions and 3229 deletions

View file

@ -1,3 +1 @@
⍝⍝ Also works with GNU APL after introduction of
⍝⍝ the ⍸ function with SVN r1368, Dec 03 2020
0=(100).|100
0=(100).|100

View file

@ -0,0 +1 @@
0=(100).|100

View file

@ -1,9 +1,9 @@
var .doors = [false] * 100
var doors = [false] * 100
for .i of .doors {
for .j = .i; .j <= len(.doors); .j += .i {
.doors[.j] = not .doors[.j]
for i of doors {
for j = i; j <= len(doors); j += i {
doors[j] = not doors[j]
}
}
writeln for[=[]] .i of .doors { if(.doors[.i]: _for ~= [.i]) }
writeln for[=[]] i of doors { if doors[i]: _for = more(_for, i) }

View file

@ -1 +1 @@
writeln foldfrom(fn(.a, .b, .c) if(.b: .a~[.c]; .a), [], .doors, series 1..len .doors)
writeln foldfrom(fn a, b, c: if(b: a~[c]; a), [], doors, series(1..len(doors)))

View file

@ -1 +1 @@
writeln map fn{^2}, 1..10
writeln map(fn{^2}, 1..10)

View file

@ -1,27 +0,0 @@
MODULE Doors;
IMPORT Out;
PROCEDURE Do*; (* In Oberon an asterisk after an identifier is an export mark *)
CONST N = 100; len = N + 1;
VAR i, j: INTEGER;
closed: ARRAY len OF BOOLEAN; (* Arrays in Oberon always start with index 0; closed[0] is not used *)
BEGIN
FOR i := 1 TO N DO closed[i] := TRUE END;
FOR i := 1 TO N DO
j := 1;
WHILE j < len DO
IF j MOD i = 0 THEN closed[j] := ~closed[j] END; INC(j) (* ~ = NOT *)
END
END;
(* Print a state diagram of all doors *)
FOR i := 1 TO N DO
IF (i - 1) MOD 10 = 0 THEN Out.Ln END;
IF closed[i] THEN Out.String("- ") ELSE Out.String("+ ") END
END; Out.Ln;
(* Print the numbers of the open doors *)
FOR i := 1 TO N DO
IF ~closed[i] THEN Out.Int(i, 0); Out.Char(" ") END
END; Out.Ln
END Do;
END Doors.

View file

@ -11,11 +11,10 @@ fn main(){
doors[current - 1] = true
increment++
door_nbr += 2 * increment + 1
}
print('O')
} else {
print('=')
}
}
doors.map( fn( it bool) bool { // graphically represent opened doors
print( if it {( 'O')} else {('=')} )
return it
})
println('')
}

View file

@ -0,0 +1,5 @@
fn main() {
for i in 1..11 {
print ( " Door ${i*i} is open.\n" )
}
}

View file

@ -0,0 +1,49 @@
module OneHundredPrisoners {
@Inject Console console;
void run() {
console.print($"# of executions: {attempts}");
console.print($"Optimal play success rate: {simulate(tryOpt)}%");
console.print($" Random play success rate: {simulate(tryRnd)}%");
}
Int attempts = 10000;
Dec simulate(function Boolean(Int[]) allFoundNumber) {
Int[] drawers = new Int[100](i->i);
Int pardoned = 0;
for (Int i : 1..attempts) {
if (allFoundNumber(drawers.shuffled())) {
++pardoned;
}
}
return (pardoned * 1000000 / attempts).toDec() / 10000;
}
Boolean tryRnd(Int[] drawers) {
Inmates: for (Int inmate : 0..<100) {
Int[] choices = drawers.shuffled();
for (Int attempt : 0..<50) {
if (drawers[choices[attempt]] == inmate) {
continue Inmates;
}
}
return False;
}
return True;
}
Boolean tryOpt(Int[] drawers) {
Inmates: for (Int inmate : 0..<100) {
Int choice = inmate;
for (Int attempt : 0..<50) {
if (drawers[choice] == inmate) {
continue Inmates;
}
choice = drawers[choice];
}
return False;
}
return True;
}
}

View file

@ -0,0 +1,40 @@
FUNCTION trials(prisoners, iterations, optimal)
DIM drawers(100)
FOR i = 1 TO prisoners
LET drawers(i) = i
NEXT i
FOR i = 1 TO iterations
FOR k = 1 TO prisoners
LET x = RND+1
LET p = drawers(x)
LET drawers(x) = drawers(k)
LET drawers(k) = p
NEXT k
FOR prisoner = 1 TO prisoners
LET found = false
IF optimal<>0 THEN LET drawer = prisoner ELSE LET drawer = RND+1
FOR j = 1 TO prisoners/2
LET drawer = drawers(drawer)
IF drawer = prisoner THEN
LET found = true
EXIT FOR
END IF
IF (NOT optimal<>0) THEN LET drawer = RND+1
NEXT j
IF (NOT found<>0) THEN EXIT FOR
NEXT prisoner
LET pardoned = pardoned+found
NEXT i
LET trials = (100*pardoned/iterations)
END FUNCTION
LET false = 0
LET true = 1
LET iterations = 10000
PRINT "Simulation count: "; iterations
FOR prisoners = 10 TO 100 STEP 90
LET randon = trials(prisoners,iterations,false)
LET optimal = trials(prisoners,iterations,true)
PRINT "Prisoners: "; prisoners; ", random: "; randon; ", optimal: "; optimal
NEXT prisoners
END

View file

@ -0,0 +1,178 @@
// Игра в 15 PABCWork.NET\Samples\Games\15.pas
uses GraphABC,ABCObjects,ABCButtons;
const
/// размер поля
n = 4;
/// размер фишки
sz = 100;
/// зазор между фишками
zz = 10;
/// отступ от левого и правого краев
x0 = 20;
/// отступ от верхнего и нижнего краев
y0 = 20;
var
p: array [1..n,1..n] of SquareABC;
digits: array [1..n*n-1] of integer;
MeshButton: ButtonABC;
StatusRect: RectangleABC;
EmptyCellX,EmptyCellY: integer;
MovesCount: integer;
EndOfGame: boolean; // True если все фишки стоят на своих местах
// Поменять местами две фишки
procedure Swap(var p,p1: SquareABC);
begin
PABCSystem.Swap(p,p1);
var i := p.Left;
p.Left := p1.Left;
p1.Left := i;
i := p.Top;
p.Top := p1.Top;
p1.Top := i;
end;
// Определить, являются ли клетки соседями
function Neighbours(x1,y1,x2,y2: integer): boolean;
begin
Result := (Abs(x1-x2)=1) and (y1=y2) or (Abs(y1-y2)=1) and (x1=x2)
end;
// Заполнить вспомогательный массив цифр
procedure FillDigitsArr;
begin
for var i:=1 to n*n-1 do
digits[i] := i;
end;
// Перемешать вспомогательный массив цифр. Количество обменов должно быть четным
procedure MixDigitsArr;
var x: integer;
begin
for var i:=1 to n*n-1 do
begin
repeat
x := Random(15)+1;
until x<>i;
Swap(digits[i],digits[x]);
end;
if n mod 2=0 then
Swap(digits[1],digits[2]); // количество обменов должно быть четным
end;
// Заполнить двумерный массив фишек. Вместо пустой ячейки - белая фишка с числом 0
procedure Fill15ByDigitsArr;
begin
Swap(p[EmptyCellY,EmptyCellX],p[n,n]); // Переместить пустую фишку в правый нижний угол
EmptyCellX := n;
EmptyCellY := n;
var i := 1;
for var y:=1 to n do
for var x:=1 to n do
begin
if x*y=n*n then exit;
p[y,x].Number := digits[i];
i += 1;
end;
end;
// Перемешать массив фишек
procedure Mix15;
begin
MixDigitsArr;
Fill15ByDigitsArr;
MovesCount := 0;
EndOfGame := False;
StatusRect.Text := 'Количество ходов: '+IntToStr(MovesCount);
StatusRect.Color := RGB(200,200,255);
end;
// Создать массив фишек
procedure Create15;
begin
EmptyCellX := n;
EmptyCellY := n;
for var x:=1 to n do
for var y:=1 to n do
begin
p[y,x] := new SquareABC(x0+(x-1)*(sz+zz),y0+(y-1)*(sz+zz),sz,clMoneyGreen);
p[y,x].BorderColor := clGreen;
p[y,x].BorderWidth := 2;
p[y,x].TextScale := 0.7;
end;
p[EmptyCellY,EmptyCellX].Color := clWhite;
p[EmptyCellY,EmptyCellX].BorderColor := clWhite;
FillDigitsArr;
MixDigitsArr;
Fill15ByDigitsArr;
end;
// Проверить, все ли фишки стоят на своих местах
function IsSolution: boolean;
begin
Result:=True;
var i:=1;
for var y:=1 to n do
for var x:=1 to n do
begin
if p[y,x].Number<>i then
begin
Result:=False;
break;
end;
i += 1;
if i=n*n then i:=0;
end;
end;
procedure MouseDown(x,y,mb: integer);
begin
if EndOfGame then // Если все фишки на своих местах, то не реагировать на мышь и ждать нажатия кнопки "Перемешать"
exit;
if ObjectUnderPoint(x,y)=nil then // Eсли мы щелкнули не на объекте, то не реагировать на мышь
exit;
var fx := (x-x0) div (sz+zz) + 1; // Вычислить координаты на доске для ячейки, на которой мы щелкнули мышью
var fy := (y-y0) div (sz+zz) + 1;
if (fx>n) or (fy>n) then
exit;
if Neighbours(fx,fy,EmptyCellX,EmptyCellY) then // Если ячейка соседствует с пустой, то поменять их местами
begin
Swap(p[EmptyCellY,EmptyCellX],p[fy,fx]);
EmptyCellX := fx;
EmptyCellY := fy;
Inc(MovesCount);
StatusRect.Text := 'Количество ходов: ' + MovesCount;
if IsSolution then
begin
StatusRect.Text := 'Победа! Сделано ходов: ' + MovesCount;
StatusRect.Color := RGB(255,200,200);
EndOfGame := True;
end
end;
end;
begin
SetSmoothingOff;
Window.Title := 'Игра в 15';
Window.IsFixedSize := True;
SetWindowSize(2*x0+(sz+zz)*n-zz,2*y0+(sz+zz)*n-zz+90);
EndOfGame := False;
Create15;
MeshButton := ButtonABC.Create((WindowWidth-200) div 2,2*y0+(sz+zz)*n-zz,200,'Перемешать',clLightGray);
MeshButton.OnClick := Mix15;
StatusRect := new RectangleABC(0,WindowHeight-40,WindowWidth,40,RGB(200,200,255));
StatusRect.TextVisible := True;
StatusRect.Text := 'Количество ходов: '+IntToStr(MovesCount);
StatusRect.BorderWidth := 2;
StatusRect.BorderColor := RGB(80,80,255);
MovesCount := 0;
OnMouseDown := MouseDown;
end.

View file

@ -0,0 +1,91 @@
const std = @import("std");
const stdout = std.io.getStdOut().writer();
const tokens = [16][]const u8{ " 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", "10", "11", "12", "13", "14", "15", " " };
const empty_token = 15;
var empty: u8 = empty_token;
var cells: [16]u8 = undefined;
var invalid: bool = false;
const Move = enum { no, up, down, left, right };
fn showBoard() !void {
try stdout.writeAll("\n");
var solved = true;
var i: u8 = 0;
while (i < 16) : (i += 1) {
try stdout.print(" {s} ", .{tokens[cells[i]]});
if ((i + 1) % 4 == 0) try stdout.writeAll("\n");
if (i != cells[i]) solved = false;
}
try stdout.writeAll("\n");
if (solved) {
try stdout.writeAll("\n\n** You did it! **\n\n");
std.posix.exit(0);
}
}
fn updateToken(move: Move) !void {
const newEmpty = switch (move) {
Move.up => if (empty / 4 < 3) empty + 4 else empty,
Move.down => if (empty / 4 > 0) empty - 4 else empty,
Move.left => if (empty % 4 < 3) empty + 1 else empty,
Move.right => if (empty % 4 > 0) empty - 1 else empty,
else => empty,
};
if (empty == newEmpty) {
invalid = true;
} else {
invalid = false;
cells[empty] = cells[newEmpty];
cells[newEmpty] = empty_token;
empty = newEmpty;
}
}
fn waitForMove() !Move {
const reader = std.io.getStdIn().reader();
if (invalid) try stdout.writeAll("(invalid) ");
try stdout.writeAll("enter u/d/l/r or q: ");
const input = try reader.readBytesNoEof(2);
switch (std.ascii.toLower(input[0])) {
'q' => std.posix.exit(0),
'u' => return Move.up,
'd' => return Move.down,
'l' => return Move.left,
'r' => return Move.right,
else => return Move.no,
}
}
fn shuffle(moves: u8) !void {
var random = std.rand.DefaultPrng.init(@intCast(std.time.microTimestamp()));
const rand = random.random();
var n: u8 = 0;
while (n < moves) {
const move: Move = rand.enumValue(Move);
try updateToken(move);
if (!invalid) n += 1;
}
invalid = false;
}
pub fn main() !void {
var n: u8 = 0;
while (n < 16) : (n += 1) {
cells[n] = n;
}
try shuffle(50);
try showBoard();
while (true) {
try updateToken(try waitForMove());
try showBoard();
}
}

View file

@ -0,0 +1,78 @@
import 'package:collection/collection.dart';
typedef OffsetFunction = int Function(int a, int b);
Function eq = const ListEquality().equals;
/// Solve Random 15 Puzzles
class FifteenSolver {
static const target = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0];
static const trN = [3, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3];
static const tcN = [3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2];
var pos0 = List.filled(100, 0);
var moves = List.filled(100, 0);
var dirs = List.filled(100, '');
int step = 0, best = 0;
var board = List.generate(100, (int i) => List.filled(16, 0));
bool isFinished() {
if (moves[step] < best) return nextMove();
if (eq(board[step], target)) {
print("Solution found in $step moves :${dirs.join('')}");
return true;
}
return (moves[step] == best) ? nextMove() : false;
}
var passNumber = 0;
/// Try all valid moves from here, but don't retrace your steps.
/// Return true if a solution is found.
bool nextMove() {
// if (passNumber++ ~/ 100000 == 0) print("${dirs.join('')}");
return (dirs[step] != 'u' && pos0[step] ~/ 4 < 3 && down()) ||
(dirs[step] != 'd' && pos0[step] ~/ 4 > 0 && up()) ||
(dirs[step] != 'l' && pos0[step] % 4 < 3 && right()) ||
(dirs[step] != 'r' && pos0[step] % 4 > 0 && left()) ||
false;
}
bool move(int offset, String dir, List<int> rcArray, OffsetFunction rcFunc) {
final int ix = pos0[step] + offset;
final n = board[step][ix];
pos0[step + 1] = pos0[step] + offset;
board[step + 1] = board[step].toList()
..[pos0[step]] = n
..[ix] = 0;
dirs[step + 1] = dir;
moves[step + 1] = moves[step] + rcFunc(rcArray[n], pos0[step]);
step++;
if (isFinished()) return true;
step--;
return false;
}
bool right() => move(1, 'r', tcN, (a, b) => (a <= b % 4 ? 0 : 1));
bool left() => move(-1, 'l', tcN, (a, b) => (a >= b % 4 ? 0 : 1));
bool down() => move(4, 'd', trN, (a, b) => (a <= b ~/ 4 ? 0 : 1));
bool up() => move(-4, 'u', trN, (a, b) => (a >= b ~/ 4 ? 0 : 1));
void solve(List<int> initBoard) {
pos0[0] = initBoard.indexOf(0);
board[0] = initBoard;
while (!isFinished()) best++;
}
}
void main(List<String> args) {
print("running");
// test values
// final start = [5, 1, 2, 3, 6, 10, 7, 4, 13, 9, 11, 8, 14, 0, 15, 12];
// final start = [9, 1, 2, 4, 13, 6, 5, 7, 3, 11, 14, 15, 10, 0, 8, 12];
// final start = [10, 3, 1, 4, 13, 5, 8, 7, 9, 6, 0, 11, 14, 15, 12, 2];
// required solution
final start = [15, 14, 1, 6, 9, 11, 4, 12, 0, 10, 7, 3, 13, 8, 5, 2];
// Extra credit
// final start = [0, 12, 9, 13, 15, 11, 10, 14, 3, 7, 2, 5, 4, 8, 6, 1];
print(start);
FifteenSolver().solve(start);
}

View file

@ -0,0 +1,47 @@
# Solve a 15 puzzle https://rosettacode.org/wiki/15_puzzle_solver#Uiua
# Experimental!
T ← ↯4_4 ↻1⇡16
# Return shuffled copy of the input.
Shuffle ← ⊏⊸(⍏[⍥⚂]⧻)
# Positions of the numbers (not 0)
Pos ← ≡(⊢⊚⌕)↘1⇡16¤
# Applying a very gentle weighting to certain cells massively
# speeds up the algorithm
Weights ← [[2 1 1 2] [2 1 1 2] [2 1 1 2] [2 1 1 1]]
Distance ← /+×⊡:Weights:≡/+⌵-⊙.∩Pos
Heuristic ← Distance T
# Four possible neighbours
Nfour ← [[1 0] [¯1 0] [0 1] [0 ¯1]]
# Actual neighbours at a point.
ValidN ← ≡(⊂)⊙¤:⟜(▽⊸(≥0≡/↧)▽⊸(<4≡/↥)+Nfour)¤
# Precalculate them.
ValidNs ← ⊞(□ ValidN⊟)⇡4 ⇡4
# Get the valid (from to) moves from this cell.
Moves ← °□⊡:ValidNs⊢⊚⌕0
# Swap the values at the indexes [0 1] [a b 2 3] -> [b a 2 3]
Swap ← ⍜(⊡|∘◌) ⊃(⇌⊙∘|⊡)
# List the possible next positions for a position
Next ← ⊙◌≡(Swap ⊙.)⊙¤⊸Moves
Solve ← (
&p"Running..."&p.
⍜nowastar(Next|Heuristic|≍T)
&p$"_ seconds"
# Track the movement of the 0 between adjacent steps.
≡(/-)◫2◇≡(⊢⊚⌕0)⇌⊢
# Map each to a direction string and join.
/⊂⇌≡⍣("d" °¯1_0|"u" °1_0|"r" °0_¯1|"l" °0_1|∘)
)
# Uncomment one of the following lines to try random grids
# ⍥(Swap⊡⊸(⌊×⚂⧻)⊸Moves)90 T
# [[2 14 6 4] [5 1 3 8] [9 10 7 11] [13 0 15 12]] # Simple 40 shuffles
# [[5 1 2 3] [6 10 7 4] [13 9 11 8] [14 0 15 12]] # Simple 12 steps
# [[9 1 2 4] [13 6 5 7] [3 11 14 15] [10 0 8 12]] # 34 steps
# [[10 3 1 4] [13 5 8 7] [9 6 0 11] [14 15 12 2]] # 38 steps (a few seconds)
[[15 14 1 6] [9 11 4 12] [0 10 7 3] [13 8 5 2]] # Main Challenge
# [[0 12 9 13] [15 11 10 14] [3 7 2 5] [4 8 6 1]] # Extra Credit
Solve

127
Task/2048/Jq/2048.jq Normal file
View file

@ -0,0 +1,127 @@
include "MRG32k3a" {search: "."}; # see comment above
### Generic functions
def lpad($len): tostring | ($len - length) as $l | (" " * $l) + .;
# Create an m x n matrix with initial values specified by .
def matrix($m; $n):
if $m == 0 then []
else . as $init
| if $m == 1 then [range(0;$n) | $init]
elif $m > 0 then
matrix(1; $n) as $row
| [range(0; $m) | $row ]
else error("matrix\($m);\($n)) invalid")
end
end;
### The 2048 Game
# Left-squish the input array in accordance with the game requirements for a single row
def squish:
def squish($n):
def s:
if length == 0 then [range(0;$n)|null]
elif .[0] == null then .[1:] | s
elif length == 1 then . + [range(0; $n - 1)|null]
elif .[0] == .[1] then [.[0] + .[1]] + (.[2:]|squish($n-1))
else .[0:1] + (.[1:]|squish($n-1))
end;
s;
squish(length);
# Input: a matrix of rows
def squish_left:
[.[] | squish];
def squish_right:
[.[] | reverse | squish | reverse];
def squish_up:
transpose
| [.[] | squish]
| transpose;
def squish_down:
transpose
| [.[] | reverse | squish | reverse]
| transpose;
# Gather the [i,j] co-ordinates of all the null values in the input matrix
def gather:
if length == 0 then error end
| (.[0] | length) as $cols
| [range(0;length) as $i
| range(0; $cols) as $j
| select(.[$i][$j] == null) | [$i,$j]]
| if length == 0 then error end ;
# Input: {matrix}
# Add a random 2 or 4 if possible, else error
# Output: includes .prng for the PRN generator
def add_random:
(.matrix | gather) as $gather
| ($gather | length) as $n
| if $n == 0 then error end
| if .prng == null then .prng = seed(now | tostring | sub("^.*[.]";"") | tonumber) end
| .prng |= nextFloat
| $gather[.prng.nextFloat * $n | trunc] as [$i,$j]
| .prng |= nextFloat
| (if (.prng.nextFloat) < 0.1 then 4 else 2 end) as $exmachina
| .matrix[$i][$j] = $exmachina ;
def prompt: "[ijkl] or [wasd] or q to quit or n to restart:";
def direction:
{"i": "up", "j": "left", "k": "down", "l": "right",
"w": "up", "a": "left", "s": "down", "d": "right",
"q": "quit",
"n": "restart"
};
# Recognize $goal as the goal
def play($goal):
# Pretty print
def pp:
.matrix[] | map(. // "." | lpad(4)) | join(" ");
def won:
any(.matrix[][]; . == $goal);
def lost:
.matrix
| (squish_left == .) and (squish_right == .) and
(squish_up == .) and (squish_down == .);
def round:
pp,
if lost then "Sorry! Better luck next time.", play($goal)
else prompt,
( (try input catch halt) as $in
| .matrix as $matrix # for checking if a move is legal
| .emit = null
| direction[$in | ascii_downcase] as $direction
| if $direction == "up" then .matrix |= squish_up
elif $direction == "down" then .matrix |= squish_down
elif $direction == "left" then .matrix |= squish_left
elif $direction == "right" then .matrix |= squish_right
elif $direction == "quit" then .emit = "bye"
elif $direction == "restart" then .emit = "restart"
else .emit = "unknown direction \($direction) ... please try again."
end
| if .emit == "bye" then .emit, halt
elif .emit == "restart" then "Restarting...", play($goal)
elif .emit != null then .emit, round
elif .matrix == $matrix then "Disallowed direction! Please try again.", round
elif won then pp, "Congratulations!", play($goal)
else add_random | round
end)
end;
{ matrix: (null | matrix(4;4))}
| .matrix[2] = [null,2,2,2]
| round;
play(2048)

View file

@ -20,13 +20,6 @@ class G2048 {
for (j in 0..3) _board[i][j] = Tile.new(0, false)
}
_rand = Random.new()
initializeBoard()
}
initializeBoard() {
for (y in 0..3) {
for (x in 0..3) _board[x][y] = Tile.new(0, false)
}
}
loop() {

View file

@ -0,0 +1,15 @@
ops = ["+", "-", "*", "/"]
chosen = new array[[4], {|x| random[1,9]}]
println[chosen]
for d = chosen.lexicographicPermute[]
multifor o = [ops, ops, ops]
{
str = "((" + d@0 + o@0 + d@1 + ")" + o@1 + d@2 + ")" + o@2 + d@3
if eval[str] == 24
println[str]
str = "(" + d@0 + o@0 + d@1 + ")" + o@1 + "(" + d@2 + + o@2 + d@3 + ")"
if eval[str] == 24
println[str]
}

View file

@ -0,0 +1,310 @@
include resources "24 Game Icon.icns"
#build CompilerOptions @"-Wno-unused-variable"
_mEdit = 2
editmenu _mEdit
begin globals
long gPosition
end globals
void local fn EraseErrorText
CGRect r
r = fn CGRectMake(10, 200, 400, 15)
rect fill r,fn ColorBlack
end fn
local fn ArcRandom( a as long, b as long ) as long
long i
cln i = (arc4random()%(b-a+1))+a;
end fn = fn floor(i)
local fn GetRandomNumbers as CFStringRef
// 96 number groups
CFArrayRef combos = @[¬
// The first 32 are easy
@"1 2 3 4", @"2 4 6 8", @"1 2 4 8", @"1 3 4 6", @"1 2 6 8",
@"2 3 4 8", @"1 3 6 9", @"1 2 7 8", @"2 3 6 8", @"1 4 6 8",
@"2 2 3 9", @"3 4 6 6", @"2 3 3 8", @"1 5 6 6", @"2 4 4 6",
@"1 3 8 8", @"2 2 6 9", @"3 3 6 9", @"1 2 5 9", @"2 4 5 5",
@"1 3 5 9", @"2 2 4 9", @"1 2 3 6", @"1 2 2 9", @"1 2 3 9",
@"1 2 4 6", @"1 2 4 4", @"1 2 2 6", @"1 3 3 6", @"1 1 4 6",
@"1 1 2 8", @"1 1 3 8",
// The middle 32 are medium
@"1 5 5 9", @"4 4 6 9", @"2 3 7 9",@"3 5 8 8", @"1 6 6 8",
@"3 3 5 6", @"1 4 5 8", @"3 3 6 7",@"2 5 5 8", @"4 4 7 9",
@"1 5 6 9", @"3 3 8 9", @"2 6 6 7",@"4 5 7 8", @"2 2 5 9",
@"2 4 6 7", @"1 5 6 8", @"3 4 7 7",@"2 5 6 6", @"3 4 5 9",
@"1 6 7 9", @"2 3 7 8", @"1 4 6 9",@"2 3 5 9", @"3 4 4 8",
@"2 5 8 9", @"1 4 8 9", @"3 3 4 9",@"2 6 7 9", @"1 3 5 7",
@"1 3 6 6", @"2 2 5 7",
// The last 32 are hard
@"1 5 7 9",@"3 4 7 9", @"2 5 7 8", @"3 4 8 9", @"3 4 5 8",
@"2 6 6 9",@"4 4 5 7", @"2 4 6 9", @"1 4 7 7", @"2 3 8 9",
@"2 3 4 7",@"3 3 4 8", @"1 3 7 9", @"2 4 5 9", @"1 3 6 8",
@"2 4 4 9",@"1 5 8 9", @"3 3 5 9", @"2 6 8 9", @"1 4 4 7",
@"2 3 6 7",@"1 3 5 8", @"2 4 7 8", @"1 3 4 7", @"2 3 5 6",
@"1 4 5 6",@"3 3 5 7", @"2 2 3 6", @"3 3 7 7", @"3 3 7 9",
@"4 4 8 9",@"2 4 8 9"]
long i = fn ArcRandom( 0, len(combos) - 1 )
gPosition = i
end fn = combos[i]
local fn EvaluateMath( equation as CFStringRef ) as CFStringRef
equation = fn StringByReplacingOccurrencesOfString( lcase(equation), @"x", @"*" )
CFStringRef result = NULL
RegularExpressionRef regex = fn RegularExpressionWithPattern( @"[0-9.]+", NSRegularExpressionCaseInsensitive, NULL )
CFArrayRef matches = fn RegularExpressionMatches( regex, equation, 0, fn CFRangeMake( 0, len(equation) ) )
NSInteger intConversions = 0
TextCheckingResultRef match
CFRange originalRange
CFRange adjustedRange
CFStringRef value
for match in matches
originalRange = fn TextCheckingResultRange( match )
adjustedRange = fn CFRangeMake( ( originalRange.location + ( intConversions * len( @".0") ) ), originalRange.length )
value = fn StringSubstringWithRange( equation, adjustedRange )
if fn StringContainsString( value, @"." )
continue
else
equation = fn StringByReplacingCharactersInRange( equation, adjustedRange, fn StringWithFormat( @"%@.0", value ) )
intConversions++
end if
next
ExceptionRef e
try
ExpressionRef expression = fn ExpressionWithFormat( equation )
CFNumberRef number = fn ExpressionValueWithObject( expression, NULL, NULL )
result = fn StringWithFormat( @"%.3f", dblval( number ) )
end try
catch (e)
result = fn StringWithFormat( @"%@", e ) : exit fn
end catch
// Test if result is an integer and, if so, return result as an integer
if( fn StringDoubleValue( result ) == fn floorf( fn StringDoubleValue( result ) ) )
result = fn ArrayFirstObject( fn StringComponentsSeparatedByString( result, @"." ) )
end if
end fn = result
local fn QuitOrPlayAlert(GameResult as CFStringRef)
alert -2,,GameResult,@"You won!",@"Quit;Play Again"
AlertButtonSetKeyEquivalent( 2, 2, @"\e" )
short result
result = alert 2
if ( result != NSAlertSecondButtonReturn ) then appterminate
end fn
local fn BuildWindow
CGRect r = fn CGRectMake( 0, 0, 580, 250)
window 1, @"24 Game", r
windowcenter(1)
WindowSetBackgroundColor(1,fn ColorBlack)
end fn
///////// Start //////////
fn BuildWindow
short d(4), i
CFStringRef CheckForDuplicates(97)
for i = 1 to 96
CheckForDuplicates(i) = @""
next i
short DuplicatesCounter
DuplicatesCounter = 0
"Main"
cls
text ,,fn colorWhite
print
print %(10,15),"Given four numbers and using just the +, -, *, and / operators; and the"
print %(10,30),"possible use of parenthesis (), enter an expression that equates to 24."
print %(10,45),"You must use all your numbers and only those numbers."
print %(10,60),"Examples: 9618 Solution 9 + 6 + 1 + 8 or 3173 Solution (3 * 7) - (1 - 4)"
print
print %(10,85),"Enter Q to quit or S to skip to the next number."
"GetFourNumbers"
CFArrayRef randomNumbers : randomNumbers= fn StringComponentsSeparatedByString( fn GetRandomNumbers, @" " )
CFStringRef RandomNumberblock : RandomNumberblock = @""
CFStringRef RandomNumberblockAdd : RandomNumberblockAdd = @""
for i = 0 to 3
// create a string from the 4 numbers
RandomNumberblockAdd = randomNumbers[i]
RandomNumberblock = fn StringByAppendingString(RandomNumberblock,RandomNumberblockAdd)
RandomNumberblock = fn StringByAppendingString(RandomNumberblock,@" ")
next i
if DuplicatesCounter = > 96
// reset counter when last number is retrieved and start from the first number block
DuplicatesCounter = 0
for i = 1 to 96
CheckForDuplicates(i) = @""
next i
end if
for i = 1 to 96
// check the current numbers with the numbers already used
if fn StringIsEqual(RandomNumberblock,CheckForDuplicates(i))
RandomNumberblock = fn StringWithString(CheckForDuplicates(DuplicatesCounter))
goto "GetFourNumbers"
end if
next i
DuplicatesCounter ++
CheckForDuplicates(DuplicatesCounter) = fn StringWithString(RandomNumberblock)
d(1) = fn StringIntegerValue( randomNumbers[0] )
d(2) = fn StringIntegerValue( randomNumbers[1] )
d(3) = fn StringIntegerValue( randomNumbers[2] )
d(4) = fn StringIntegerValue( randomNumbers[3] )
short dots = 0
//d(1) = 9:d(2) = 6:d(3) = 1:d(4) = 8 // Uncomment to test with 9618 numbers. Solution 9 + 6 + 1 + 8
//d(1) = 6:d(2) = 5:d(3) = 3:d(4) = 8 // Uncomment to test with 6538 numbers. Solution 6 / ( 5 - 3 ) * 8
//d(1) = 3:d(2) = 1:d(3) = 7:d(4) = 3 // Uncomment to test with 3773 numbers. Solution ((3 * 1) * 7) + 3
//d(1) = 4:d(2) = 2:d(3) = 7:d(4) = 1 // Uncomment to test with 4271 numbers. Solution (4 * ( 7 - 2 + 1 )
// NOTE: When using these test numbers, also uncomment dots = 0 below here to prevent misleading dot displays
if gPosition <= 32 then dots = 1
if gPosition > 32 and gPosition < 65 then dots = 2
if gPosition > 64 then dots = 3
//dots = 0 uncomment when testing the numbers above to prevent misleading dot displays
print
text ,,fn colorGreen
print %(15,110),"These are your numbers, difficulty level ";
// @"\U000026AA" is white unicode dot - Easy difficulty (One-Dot)
// @"\U0001F534" is red unicode dot - Medium difficulty (Two-Dots)
// @"\U0001F7E1" is yellow unicode dot - Hard difficulty (Three-Dots)
if dots = 1 then print @"\U000026AA Easy"
if dots = 2 then print @"\U0001F534 \U0001F534 Medium"
if dots = 3 then print @"\U0001F7E1 \U0001F7E1 \U0001F7E1 Hard"
print %(55,125)
text ,18,fn colorGreen
for i = 1 to 4
print d(i); " ";
next
print
text ,12,fn colorWhite
printf @"\n\n\n"
CFStringRef expr
bool TryAgain : TryAgain = _false
CFStringRef MessageText
CFStringRef UserInput = NULL
"InputExpression"
if TryAgain
MessageText = fn StringWithFormat( @"Enter math expression: [ '%@' was incorrect ]", expr )
UserInput = input %(10, 190), MessageText, @"123456789+-*/()qs", YES,, 0
else
UserInput = input %(10, 190), @"Enter math expression:", @"123456789+-*/()qs", YES,, 0
end if
if ( UserInput == NULL ) then "InputExpression"
expr = UserInput
if expr = @"" then "InputExpression"
if fn StringIsEqual(ucase(expr) , @"Q") then appterminate
if fn StringIsEqual(ucase(expr) , @"S") then "Main"
//check expr for validity
short j
bool GotAllNumbers : GotAllNumbers = _false
short ThisNumberPosition : ThisNumberPosition = 0
short GotaNumber : GotaNumber = 0
short TotalNumbers : TotalNumbers = 0
short ExtraNumbers:ExtraNumbers = 0
for i = 1 to len$(fn stringpascalstring(expr))
if asc(mid$(fn stringpascalstring(expr),i,1)) > 48 && asc(mid$(fn stringpascalstring(expr),i,1)) < 58
ExtraNumbers ++
end if
next i
if ExtraNumbers > 4
fn EraseErrorText
text ,,fn colorRed
TryAgain = _true
print %(10,200);"Error! Extra numbers not allowed": goto "InputExpression"
text ,,fn colorWhite
end if
for i = 1 to 4
GotaNumber = 0
for j = 0 to len(expr) -1
ThisNumberPosition = instr( j, expr, right(str( d(i)),1 ))
ThisNumberPosition ++
if ThisNumberPosition then GotaNumber = _true
next j
if GotaNumber then TotalNumbers ++
next i
if TotalNumbers => 4 then GotAllNumbers = _true
if GotAllNumbers = _false
fn EraseErrorText
text ,,fn colorRed
TryAgain = _true
print %(10,200);"ERROR! Must use all your numbers and only those numbers." : goto "InputExpression"
text ,,fn colorWhite
end if
fn EraseErrorText
if fn EvaluateMath( expr ) = _false
text ,,fn colorRed
TryAgain = _true
Print %(10,200);"Error! Incorrect math sequence."
goto "InputExpression"
text ,,fn colorWhite
end if
CFStringRef GameResult
if fn StringIntegerValue( fn EvaluateMath( expr ) ) == 24 then GameResult = @"Correct" else GameResult = @"Incorrect"
if GameResult = @"Incorrect"
TryAgain = _true
goto "InputExpression"
end if
fn QuitOrPlayAlert(GameResult)
goto "Main"
handleevents

View file

@ -0,0 +1,90 @@
### The MRG32k3a combined recursive PRNG - see above
import "MRG32k3a" as MRG {search: "."};
### Generic utilities
def sum(stream): reduce stream as $x (0; .+$x);
# like while/2 but emit the final term rather than the first one
def whilst(cond; update):
def _whilst:
if cond then update | (., _whilst) else empty end;
_whilst;
### Reverse Polish Notation
# An array of the allowed operators
def operators: "+-*/" | split("");
# If $a and $b are numbers and $c an operator, then "$a $b $c" is evaluated as an RPN expression.
# Output: {emit, result} with .emit == null if there is a valid result.
def applyOperator($a; $b; $c):
if ([$a,$b] | map(type) | unique) == ["number"]
then
if $c == "+" then {result: ($a + $b)}
elif $c == "-" then {result: ($a - $b)}
elif $c == "*" then {result: ($a * $b)}
elif ($c == "/") then {result: ($b / $a)}
else {emit: "unrecognized operator: \($c)"}
end
else {emit: "invalid number"}
end;
# Input: an array representing an RPN expression.
# Output: {emit, result} as per applyOperator/3
# Example: [1,2,3,"+","+"] | evaluate #=> 6
def evaluate:
if length == 1
then if .[0]|type == "number" then {result: .[0]}
else {emit: "invalid RPN expression"}
end
elif length < 3 then {emit: "invalid RPN expression: \(. | join(" "))"}
else . as $in
| (first( range(0; length) as $i | select(any( operators[]; . == $in[$i]) ) | $i) // null) as $ix
| if $ix == null then {emit: "invalid RPN expression"}
else applyOperator(.[$ix-2]; .[$ix-1]; .[$ix]) as $result
| if $result.result then .[:$ix-2] + [$result.result] + .[$ix+1:] | evaluate
else $result
end
end
end;
### The "24 Game"
# . is the putative RPN string to be checked.
# $four is the string of the four expected digits, in order.
# Output: {emit, result} with .emit set to "Correct!" if .result == 24
def check($four):
if (gsub("[^1-9]";"") | explode | sort | implode) != $four
then {emit: "You must use each of the four digits \($four | split("") | join(" ")) exactly once:"}
else . as $in
| {s: [], emit: null}
| [$in | split("")[] | select(. != " ")
| . as $in | explode[0] | if . >= 48 and . <= 57 then . - 48 else $in end]
| evaluate
| if .result
then if .result|round == 24 then .emit = "Correct!"
else .emit = "Value \(.result) is not 24."
end
else .emit += "\nTry again, or enter . to start again, or q to quit."
end
end ;
def run:
# Populate .digits with four non-negative digits selected at random, with replacement:
{digits: (9 | MRG::prn(4) | map(. + 1))}
| (.digits | sort | join("")) as $four
| "At the prompt, enter an RPN string (e.g. 64*1+1-), or . for a new set of four digits, or q to quit.",
"Make 24 using these digits, once each, in any order: \(.digits):",
( whilst( .stop | not;
.emit = null
| . as $state
| try input catch halt
| if IN( "q", "quit") then halt
elif . == "." then $state | .stop = true
else check($four)
| if .result then .stop = true end
end )
| select(.emit).emit ),
# rerun
run;
run

View file

@ -0,0 +1,38 @@
import math.bits
fn main ( ) {
mut n := 0
mut t := []u8{len:7}
n = solve ( 0, mut t, 1, 7, true )
println ( "$n unique solutions in 1 to 7" )
n = solve ( 0, mut t, 3, 9, true )
println("$n unique solutions in 3 to 9")
n = solve ( 0, mut t, 0, 9, false )
println("$n non-unique solutions in 0 to 9")
}
fn solve ( lvl u8, mut t []u8, low u8, high u8,unique bool ) int {
if lvl==7 {
return int(suma(t) && (!unique || isunique( t )))
}
mut cnt:=0
for v := low; v <= high; v++ {
t[lvl] = v
cnt += solve ( lvl + 1, mut t, low, high, unique )
}
return cnt
}
@[inline]
fn isunique ( t []u8 ) bool {
return bits.ones_count_32(u32(1)<<t[0] | 1<<t[1] | 1<<t[2] | 1<<t[3] | 1<<t[4] | 1<<t[5] | 1<<t[6]) == 7
}
fn suma ( t []u8 ) bool {
s1 := t[0] + t[1]
s2 := t[1] + t[2] + t[3]
s3 := t[3] + t[4] + t[5]
s4 := t[5] + t[6]
return s1 == s2 && s2 == s3 && s3 == s4
}

View file

@ -0,0 +1,50 @@
const print = @import("std").debug.print;
var cnt: u32 = 0;
var t: [7]u8 = .{0} ** 7;
fn sum() bool {
const s1 = t[0] + t[1];
const s2 = t[1] + t[2] + t[3];
const s3 = t[3] + t[4] + t[5];
const s4 = t[5] + t[6];
return s1 == s2 and s2 == s3 and s3 == s4;
}
fn valid(comptime min: u16) bool {
if (sum()) {
var s: u16 = 0;
inline for (t) |v| {
s |= @as(u16, 1) << @intCast(v - min);
}
return s == 0x7F;
}
return false;
}
fn valid_non_unique(comptime min: u16) bool {
_ = min;
return sum();
}
fn solver(lvl: u32, comptime min: u16, comptime max: u16, comptime f_valid: fn (comptime u16) bool) bool {
if (lvl == 7) return f_valid(min);
for (min..max) |i| {
t[lvl] = @intCast(i);
if (solver(lvl + 1, min, max, f_valid)) cnt += 1;
}
return false;
}
fn solve(comptime min: u8, comptime max: u8, comptime f: fn (comptime u16) bool) void {
cnt = 0;
_ = solver(0, min, max + 1, f);
const str = if (f == valid) "" else "non-";
print("{d} {s}unique solutions in {} to {}\n", .{ cnt, str, min, max });
}
pub fn main() void {
solve(1, 7, valid);
solve(3, 9, valid);
solve(0, 9, valid_non_unique);
}

View file

@ -0,0 +1,63 @@
const std = @import("std");
const print = std.debug.print;
const bigint = std.math.big.int.Managed;
const eql = std.mem.eql;
const Array = std.ArrayList;
const Array1 = Array(bigint);
const Array2 = Array(Array1);
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
fn cumu(cache: *Array2, n: usize) !*Array1 {
var y = cache.items.len;
while (cache.items.len <= n) : (y += 1) {
var roww = Array1.init(allocator);
try roww.append(try bigint.init(allocator));
for (1..y + 1) |x| {
var cache_value = try cache.items[y - x].items[@min(x, y - x)].clone();
try cache_value.add(&cache_value, &roww.getLast());
try roww.append(cache_value);
}
try cache.append(roww);
}
return &(cache.items[n]);
}
fn row(cache: *Array2, n: usize) !void {
const e = try cumu(cache, n);
var v = try bigint.init(allocator);
for (0..n) |i| {
try v.sub(&e.items[i + 1], &e.items[i]);
print(" {} ", .{v});
}
v.deinit();
print("\n", .{});
}
pub fn main() !void {
var cache = Array2.init(allocator);
defer {
cache.deinit();
}
defer {
while (cache.popOrNull()) |l| {
l.deinit();
}
}
var cache0 = Array1.init(allocator);
var v = try bigint.init(allocator);
try v.set(1);
try cache0.append(v);
try cache.append(cache0);
print("rows:\n", .{});
for (1..1000) |x| {
try row(&cache, x);
}
print("\nsums:\n", .{});
for ([_]usize{ 23, 123, 999 }) |num| {
const r = try cumu(&cache, num);
print("{d: >4} {d}\n", .{ num, r.getLast() });
}
}

View file

@ -0,0 +1,35 @@
const std = @import("std");
const print = std.debug.print;
const bigint = std.math.big.int.Managed;
const eql = std.mem.eql;
const Array = std.ArrayList;
const Array1 = Array(bigint);
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
fn calc ( n:usize, p:*Array1) !void {
for ( 1..n+1 ) |k| {
var d:i64 = @intCast(n);
d -= @intCast(k*(3*k - 1)/2);
inline for ( 0..2 ) |_| {
if ( d < 0 ) return;
if (k&1>0) try p.items[n].add ( &p.items[n], &p.items[@intCast(d)] )
else try p.items[n].sub ( &p.items[n], &p.items[@intCast(d)] );
d -= @intCast(k);
}
}
}
fn main() !void {
const s = [_]usize{ 23, 123, 1234, 12345, 123456 };
var p = Array1.init ( allocator );
try p.append ( try bigint.initSet ( allocator, 1 ) );
var i:usize=1;
for ( s )|m|{
while (i<=m):(i+=1){
try p.append( try bigint.init(allocator) );
try calc( i, &p );
}
print("P({d}) = {d}\n", .{m,p.items[m]} );
}
}

View file

@ -0,0 +1,26 @@
\ 99 bottles of beer on the wall:
[
"no more bottles" ,
"one bottle" ,
( dup . " bottles" )
] var, bottles
: .bottles
dup 2 n:min bottles @ caseof ;
: .beer
.bottles . " of beer" . ;
: .wall
.beer " on the wall" . ;
: .take
" Take one down and pass it around" . ;
: beers
.wall ", " . .beer '; putc cr
n:1- 0 max .take ", " .
.wall '. putc cr drop ;
' beers 1 99 loop-
bye

View file

@ -0,0 +1,12 @@
[
( "Just one more bottle of beer on the wall, one bottle of beer.\n" . ) ,
( I dup "%d bottles of beer on the wall, %d bottles of beer.\n" s:strfmt . )
] constant lyrics
: app:main
(
dup lyrics [2,99] rot ' n:cmp a:pigeon w:exec
n:1- "Take one down, pass it around, %d bottles of beer on the wall.\n\n" s:strfmt .
) 1 99 loop-
"No more bottles of beer on the wall, no more bottles of beer.\n" . ;

View file

@ -1,20 +0,0 @@
\ 99 bottles of beer on the wall:
: allout "no more bottles" ;
: just-one "1 bottle" ;
: yeah! dup . " bottles" ;
[
' allout ,
' just-one ,
' yeah! ,
] var, bottles
: .bottles dup 2 n:min bottles @ swap caseof ;
: .beer .bottles . " of beer" . ;
: .wall .beer " on the wall" . ;
: .take " Take one down and pass it around" . ;
: beers .wall ", " . .beer '; putc cr
n:1- 0 max .take ", " .
.wall '. putc cr drop ;
' beers 1 99 loop- bye

View file

@ -0,0 +1,21 @@
namespace _99_beers;
method bottles(number: Integer): String;
begin
if (number = 1) then
Result := "bottle"
else
Result := "bottles";
end;
begin
for n: Integer := 99 downto 1 do
begin
writeLn($"{n} {bottles(n)} of beer on the wall,");
writeLn($"{n} {bottles(n)} of beer,");
writeLn($"Take one down, and pass it around,");
writeLn($"{n-1} {bottles(n-1)} of beer on the wall.");
writeLn();
end;
readLn;
end.

View file

@ -0,0 +1,10 @@
begin
for var i:=99 to 1 step -1 do
begin
Println(i,'bottles of beer on the wall');
Println(i,'bottles of beer');
Println('Take one down, pass it around');
Println(i-1,'bottles of beer on the wall');
Println
end;
end.

View file

@ -0,0 +1,10 @@
begin
for var i:=99 to 1 step -1 do
begin
writeLn($'{i} bottles of beer on the wall');
writeLn($'{i} bottles of beer');
writeLn($'Take one down, pass it around');
writeLn($'{i-1}bottles of beer on the wall');
writeLn
end;
end.

View file

@ -0,0 +1,3 @@
##
var (a,b) := ReadInteger2;
Writeln(a + b);

25
Task/A+B/Zig/a+b.zig Normal file
View file

@ -0,0 +1,25 @@
const std = @import("std");
const stdout = std.io.getStdOut().writer();
const Input = enum { a, b };
pub fn main() !void {
var buf: [1024]u8 = undefined;
const reader = std.io.getStdIn().reader();
const input = try reader.readUntilDelimiter(&buf, '\n');
const values = std.mem.trim(u8, input, "\x20");
var count: usize = 0;
var split: usize = 0;
for (values, 0..) |c, i| {
if (!std.ascii.isDigit(c)) {
count += 1;
if (count == 1) split = i;
}
}
const a = try std.fmt.parseInt(u64, values[0..split], 10);
const b = try std.fmt.parseInt(u64, values[split + count ..], 10);
try stdout.print("{d}\n", .{a + b});
}

View file

@ -0,0 +1,11 @@
A ← ↯∞_2⊞⊟."ADFGVX"
P ← ⊏⍏[⍥⚂]⧻."ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
K ← "PACKHORSE"
Sw ← ⊜□≠" ".
Polybius ← setinv(/⊂⊡≡(⊚⌕):⊙:¤P A|⊏:P≡(⊢⊚⌕)⊙¤∩≡□↯∞_2:A)
SortByK ← setinv(⊏⍏⟜(⍉⬚" "↯⊟∞⧻)K|▽≠" "./⊂⍉⊏⍏⍏K)
Str ← setinv(/$"_ _"Sw/⊂≡(⊂:" ")|≡(⊢°□◇⬚" "↯⊟∞)/↥≡◇⧻.Sw)
Pt ← "ATTACKAT1200AM"
&p $"Key = _\nPolybius:\n_\nPlaintext = _"K↯⊟.√⧻.P Pt
&p$"Crypttext = _". Str SortByK Polybius Pt
&p$"Plaintext = _" °Polybius °SortByK °Str

View file

@ -0,0 +1,93 @@
// RosettaCode Editing ASCII Art Diagram Converter
include "NSLog.incl"
local fn HexToBinary( hexString as CFStringRef ) as CFStringRef
NSUInteger i
CFMutableStringRef binaryString = fn MutableStringNew
CFDictionaryRef hexToBinaryMap = @{
@"0": @"0000", @"1": @"0001", @"2": @"0010", @"3": @"0011",
@"4": @"0100", @"5": @"0101", @"6": @"0110", @"7": @"0111",
@"8": @"1000", @"9": @"1001", @"A": @"1010", @"B": @"1011",
@"C": @"1100", @"D": @"1101", @"E": @"1110", @"F": @"1111"}
for i = 0 to len(hexString) - 1
CFStringRef hexDigit = ucase( fn StringSubstringWithRange( hexString, fn CFRangeMake( i, 1 ) ) )
CFStringRef binaryDigit = ucase( hexToBinaryMap[hexDigit] )
if ( binaryDigit )
MutableStringAppendString( binaryString, binaryDigit )
end if
next
end fn = binaryString
local fn ParseASCIIArt
CFStringRef header = @"¬
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n¬
| ID |\n¬
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n¬
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |\n¬
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n¬
| QDCOUNT |\n¬
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n¬
| ANCOUNT |\n¬
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n¬
| NSCOUNT |\n¬
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n¬
| ARCOUNT |\n¬
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+"
NSInteger i = 0, tempBits
CFMutableArrayRef table = fn MutableArrayNew
RegularExpressionRef regex = fn RegularExpressionWithPattern( @"\\| *\\w+ *", 0, NULL )
CFArrayRef matches = fn RegularExpressionMatches( regex, header, 0, fn CFRangeMake( 0, len(header) ) )
TextCheckingResultRef match
CFDictionaryRef dict
CFStringRef tempName, binaryStr
CFRange tempRange
for match in matches
CFRange range = fn TextCheckingResultRange( match )
CFCharacterSetRef charSet = fn CharacterSetWithCharactersInString( @"| " )
CFStringRef name = fn StringByTrimmingCharactersInSet( fn StringSubstringWithRange( header, range ), charSet )
NSInteger bits = range.length / 3
ValueRef rangeVal = fn ValueWithRange( fn CFRangeMake( i, bits ) )
CFDictionaryRef item = @{@"name":name, @"bits":fn NumberWithInteger( bits ), @"range":rangeVal}
MutableArrayAddObject( table, item )
i += bits
next
NSLog( @"\nRFC 1035 message diagram header:\n%@\n", header )
CFStringRef hexStr = @"78477bbf5496e12e1bf169a4"
CFStringRef binStr = fn HexToBinary( @"78477bbf5496e12e1bf169a4" )
NSLog( @" Decoded:" )
NSLog( @" Name Bits Start End" )
NSLog( @" ======= ==== ===== ===" )
for dict in table
tempName = dict[@"name"]
tempBits = fn NumberIntegerValue( dict[@"bits"] )
tempRange = fn ValueRange( dict[@"range"] )
NSLog( @"%8s %5ld %6ld %4ld", fn StringUTF8String( tempName ), tempBits, tempRange.location, tempRange.location + tempRange.length - 1 )
next
NSLog( @"\n Test string in hex:\n %@\n", hexStr )
NSLog( @" Test string in binary:\n %@\n", binStr )
NSLog( @" Unpacked:" )
NSLog( @" Name Size Bit Pattern" )
NSLog( @" ======= ==== ================" )
for dict in table
tempName = dict[@"name"]
tempBits = fn NumberIntegerValue( dict[@"bits"] )
tempRange = fn ValueRange( dict[@"range"] )
binaryStr = fn StringSubstringWithRange( binStr, fn CFRangeMake( tempRange.location, tempBits ) )
NSLog( @"%8s %5ld %-7s", fn StringUTF8String( tempName ), tempBits, fn StringUTF8String( binaryStr ) )
next
end fn
fn ParseASCIIArt
HandleEvents

View file

@ -0,0 +1,26 @@
HtoB ← /⊂⋯⊗:"0123456789abcdef"
Fields ← (
⊜□≠@|./⊂▽⊸≡(¬∊@+)⊜∘≠@\n.
⊃(≡(÷3+1◇⧻)|≡(□(◇▽⊸⍚≥@A)))
)
T ← $ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
$ | ID |
$ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
$ |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
$ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
$ | QDCOUNT |
$ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
$ | ANCOUNT |
$ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
$ | NSCOUNT |
$ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
$ | ARCOUNT |
$ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
◫2⊂0\+Fields T # Get field starts and ends.
HtoB "78477bbf5496e12e1bf169a4"
⍚⊏⊙¤≡(□↘⊙⇡°⊟), # Split the bits.
≡⊂:≡⊂:⊙(≡(⊂:⊟⊙(-1)°⊟⟜/-)) # Arrange the table.
&p$"Field\tBits\tStart\tEnd\tValue"
&p$"-----\t----\t-----\t---\t-----"
≡(&p$"_\t_\t_\t_\t_"⊃(⊡0|⊡1|⊡2|⊡3|⊡4))

View file

@ -0,0 +1,36 @@
(defun abbreviate-list (list-of-days abbreviation-length)
"Take each element of LIST-OF-DAYS and abbreviate to ABBREVIATION-LENGTH."
(let ((abbrev-list)
(abbrev-element))
(dolist (one-element list-of-days) ; loop through each day of week
;; if the day of week is at least as long as the abbreviation
(if (>= (length one-element) abbreviation-length) ; if day >= abbreviation length
(setq abbrev-element (substring one-element 0 abbreviation-length)) ; abbreviate the day of the week
(setq abbrev-element one-element)) ; otherwise don't abbreviate
(push abbrev-element abbrev-list)) ; put the abbreviated/non-abbreviated day on our list
abbrev-list)) ; return the list of abbreviated days
(defun cycle-days (list-of-days)
"Find shortest unique abbreviation in LIST-OF-DAYS list."
(let ((abbrev-list)
(abbrev-length 1)
(current-abbrev)
(looking-for-shortest-list t))
(if (= (length list-of-days) 0) ; if list-of-days is empty (i.e., blank line)
(setq looking-for-shortest-list nil)) ; then don't look for the shortest unique abbreviations
(while looking-for-shortest-list ; as long as we are looking for the shortest unique abbreviations
(setq abbrev-list (abbreviate-list list-of-days abbrev-length)) ; get a list of abbreviated day names
(if (= (length list-of-days) (length (seq-uniq abbrev-list))) ; if abbreviated list has no duplicates
(progn
(message (format "%d %s" abbrev-length list-of-days)) ; then in echo buffer show length and days
(setq looking-for-shortest-list nil)) ; also, then don't look for the shortest unique abbreviations
(setq abbrev-length (+ abbrev-length 1)))))) ; else increase the length of the abbreviation; loop to while
(defun days-of-week ()
"Find minimum abbreviation length of days of week."
(let ((current-line-list))
(find-file "Days_of_week.txt") ; open file or switch to buffer
(beginning-of-buffer) ; go to the top of the buffer
(dolist (current-line (split-string (buffer-string) "\n")) ; go line by line through buffer
(setq current-line-list (split-string current-line " ")) ; change each line into list of days of week
(cycle-days current-line-list))))

View file

@ -0,0 +1,17 @@
# Experimental!
# Find shortest distinct abbreviation length per line
Lines ← {"Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
"sing_kei_yaht sing_kei_yat sing_kei_yee sing_kei_saam sing_kei_sie sing_kei_ng sing_kei_luk"
""
"Diu_prima Diu_sequima Diu_tritima Diu_quartima Diu_quintima Diu_sextima Diu_sabbata"
"sunnudagur mánadagur tÿsdaguy mikudagur hósdagur friggjadagur leygardagur"
"Yek_Sham'beh Do_Sham'beh Seh_Sham'beh Cha'har_Sham'beh Panj_Sham'beh Jom'eh Sham'beh"}
# Return 1+max_common_prefix
AbbrevLen ← +1/↥◹(/↥↘1)⊞(/+\↧⬚@ =∩°□).
Split ← ⊜□⊸(≠@ )
RemoveEmpty ← ▽⊸(≡(≠0◇⧻))
Line ← ⊂⊂:": " °⋕:⊸(/(⊂⊂) " "≡(⬚@ ↙:°□)⊙¤)⟜AbbrevLen ◇Split
≡⍚Line RemoveEmpty Lines
≡&p

View file

@ -0,0 +1,60 @@
proc out s[] . .
for r = 0 to 2
for c to 3
write s[c + 3 * r] & " "
.
print ""
.
print ""
.
proc stab . m[] .
n = sqrt len m[]
repeat
stable = 1
for p to len m[]
if m[p] >= 4
stable = 0
m[p] -= 4
if p > n
m[p - n] += 1
.
if p mod n <> 0
m[p + 1] += 1
.
if p <= len m[] - n
m[p + n] += 1
.
if p mod n <> 1
m[p - 1] += 1
.
.
.
until stable = 1
.
.
func[] add s1[] s2[] .
for i to len s1[]
r[] &= s1[i] + s2[i]
.
stab r[]
return r[]
.
print "avalanche:"
s4[] = [ 4 3 3 3 1 2 0 2 3 ]
stab s4[]
out s4[]
#
s1[] = [ 1 2 0 2 1 1 0 1 3 ]
s2[] = [ 2 1 3 1 0 1 0 1 0 ]
if add s1[] s2[] = add s2[] s1[]
print "s1 + s2 = s2 + s1"
.
#
s3[] = [ 3 3 3 3 3 3 3 3 3 ]
s3_id[] = [ 2 1 2 1 0 1 2 1 2 ]
if add s3[] s3_id[] = s3[]
print "s3 + s3_id = s3"
.
if add s3_id[] s3_id[] = s3_id[]
print "s3_id + s3_id = s3_id"
.

View file

@ -0,0 +1,67 @@
pragma Ada_2022;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
procedure Abelian_Sandpile is
type Grid_2D is array (Positive range <>, Positive range <>) of Natural;
procedure Write_PPM (Grid : Grid_2D; Filename : String) is
PPM_File : File_Type;
begin
Create (PPM_File, Out_File, Filename);
Put_Line (PPM_File, "P3");
Put_Line (PPM_File, Grid'Length (1)'Image & Grid'Length (2)'Image);
Put_Line (PPM_File, "7");
for Y in 1 .. Grid'Length (2) loop
for X in 1 .. Grid'Length (1) loop
case Grid (X, Y) is
when 0 => Put_Line (PPM_File, "0 0 0"); -- black
when 1 => Put_Line (PPM_File, "0 7 0"); -- green
when 2 => Put_Line (PPM_File, "7 0 7"); -- lilac
when 3 => Put_Line (PPM_File, "7 7 0"); -- yellow
when others => Put_Line (PPM_File, "0 0 7"); -- blue, shouldn't happen
end case;
end loop;
end loop;
Close (PPM_File);
end Write_PPM;
begin
if Argument_Count /= 2 then
Put_Line ("Error: Must specify <Sandpile Height> <Grid Size>");
else
declare
Initial_Height : constant Positive := Positive'Value (Argument (1));
Grid_Size : constant Positive := Positive'Value (Argument (2));
Sandpile : Grid_2D (1 .. Grid_Size, 1 .. Grid_Size) := [others => [others => 0]];
More_To_Do : Boolean := True;
Overspill : Natural;
begin
Sandpile (Grid_Size / 2, Grid_Size / 2) := Initial_Height;
while More_To_Do loop
More_To_Do := False;
for X in 1 .. Grid_Size loop
for Y in 1 .. Grid_Size loop
if Sandpile (X, Y) >= 4 then
Overspill := Sandpile (X, Y) / 4;
Sandpile (X, Y) := @ mod 4;
More_To_Do := True;
if X > 1 then
Sandpile (X - 1, Y) := @ + Overspill;
end if;
if Y > 1 then
Sandpile (X, Y - 1) := @ + Overspill;
end if;
if X < Grid_Size then
Sandpile (X + 1, Y) := @ + Overspill;
end if;
if Y < Grid_Size then
Sandpile (X, Y + 1) := @ + Overspill;
end if;
end if;
end loop;
end loop;
end loop;
if Grid_Size < 16 then Put_Line (Sandpile'Image); end if;
Write_PPM (Sandpile, "sandpile.ppm");
end;
end if;
end Abelian_Sandpile;

View file

@ -0,0 +1,35 @@
n = 77
len m[] n * n
m[n * n div 2 + 1] = 10000
#
proc show . .
sc = 100 / n
for r range0 n
for c range0 n
move c * sc r * sc
p = r * n + c + 1
color 222 * m[p]
rect sc sc
.
.
sleep 0
.
proc run . .
repeat
mp[] = m[]
stable = 1
for p to len mp[]
if mp[p] >= 4
stable = 0
m[p] -= 4
m[p - n] += 1
m[p + 1] += 1
m[p + n] += 1
m[p - 1] += 1
.
.
show
until stable = 1
.
.
run

View file

@ -0,0 +1,27 @@
10 mode 1:defint a-z
20 height=15000:size=100
30 ink 0,0:ink 1,18:ink 2,8:ink 3,24
40 dim grid(size+1,size+1)
50 grid(size/2,size/2)=height
60 moretodo=1
70 while moretodo
80 moretodo=0
90 for x=1 to size
100 for y=1 to size
110 if grid(x,y)<4 then 190
120 overspill=int(grid(x,y)/4)
130 grid(x,y)=grid(x,y) mod 4
140 moretodo=1
150 if x>1 then grid(x-1,y)=grid(x-1,y)+overspill
160 if y>1 then grid(x,y-1)=grid(x,y-1)+overspill
170 if x<size then grid(x+1,y)=grid(x+1,y)+overspill
180 if y<size then grid(x,y+1)=grid(x,y+1)+overspill
190 next:next
200 wend
300 for x=1 to size
310 for y=1 to size
320 plot 4*x,4*y,grid(x,y)
330 plot 4*x+2,4*y,grid(x,y)
340 plot 4*x,4*y+2,grid(x,y)
350 plot 4*x+2,4*y+2,grid(x,y)
360 next:next

View file

@ -0,0 +1,10 @@
G ← ⍜⊡⋅6000⌊÷2⟜↯⊟.71 0 # good demo
PadTL ← ↻¯≡↥0⊙⬚°◌↙⟜(+⌵)⊙⊸△
# Pad the differences grid to same size, making ops *much* faster.
D ← ⬚0PadTL-△G △.[0_1_0 1_¯4_1 0_1_0]
Scale ← ▽⟜≡▽4÷/↥/↥. # Greyscale and upscale for output.
Abelian₁ ← ∧(+(↻¯:D))≡(-1_1)⊚≥4.⊙(+1) # Moves grains one at a time
Abelian₄ ← ∧(+×⊃(⌊÷4⊡+1_1|↻¯:D)⊙.)≡(-1_1)⊚≥4.⊙(+1) # Moves all >= 4 -- slightly faster
⟜Scale&p⍜now⍥Abelian₄ 100G 0
⟜Scale&p⍜now⍥Abelian₄ 900⊙,
Scale⍥Abelian₄∞⊙, # Run to completion

View file

@ -1,6 +1,6 @@
T AbstractQueue
F.virtual.abstract enqueue(Int item) -> N
F.virtual.abstract enqueue(Int item) -> Void
T PrintQueue(AbstractQueue)
F.virtual.assign enqueue(Int item) -> N
F.virtual.assign enqueue(Int item) -> Void
print(item)

View file

@ -0,0 +1,20 @@
type
MyAbstract = abstract class
public
procedure Proc1; abstract;
procedure Proc2;
begin
end;
end;
MyClass = class(MyAbstract)
public
procedure Proc1; override;
begin
end;
end;
begin
var a := new MyClass;
a.Proc1;
end.

View file

@ -0,0 +1,22 @@
type
IMyInterface = interface
procedure Proc1;
procedure Proc2;
end;
MyClass = class(IMyInterface)
public
procedure Proc1;
begin
Print(1);
end;
procedure Proc2;
begin
Print(2);
end;
end;
begin
var a: IMyInterface := new MyClass;
a.Proc1;
a.Proc2;
end.

View file

@ -0,0 +1,12 @@
function foo(n: real): real -> real :=
i -> begin
n += i;
Result := n;
end;
begin
var x := foo(1);
x(5);
foo(3);
print(x(2.3));
end.

View file

@ -0,0 +1,205 @@
pragma Ada_2022;
with Ada.Text_IO;
with Ada.Numerics; use Ada.Numerics;
with Ada.Numerics.Long_Elementary_Functions;
use Ada.Numerics.Long_Elementary_Functions;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Prime_Numbers;
procedure Achilles_Numbers is
package Long_Integer_Prime_Numbers is new Prime_Numbers
(Integer, 0, 1, 2);
use Long_Integer_Prime_Numbers;
-- A powerful number N is such that for every primer factor P of it
-- P^2 also divides N
-- Is_Powerful function decomposes the given number N in its prime factors
-- and then it checks if each factor squared is a divisor of N
function Is_Powerful (Number : Natural) return Boolean is
List : constant Number_List := Decompose (Integer (Number));
begin
for Index in List'Range loop
declare
N : constant Long_Long_Integer := Long_Long_Integer (Number);
F : constant Long_Long_Integer := Long_Long_Integer (List (Index));
begin
if N mod (F * F) /= 0 then
return False;
end if;
end;
end loop;
return True;
end Is_Powerful;
-- The Is_Power function checks if a given number N can be written
-- as a power of two integers that are > 1
-- It makes use of the mathematical expression N = A^B
-- taking Log(N) = Log (A^B) equals to B = Log (N) / Log (A)
-- where the solutions are when B is an integer > 1
function Is_Power (N : Integer) return Boolean is
function Is_Almost_Equal (A : Long_Float;
B : Long_Float) return Boolean is
Epsilon : constant := 0.000_000_000_000_001;
begin
if abs (A - B) < Epsilon then
return True;
else
return False;
end if;
end Is_Almost_Equal;
A : Integer := 2;
B : Long_Float;
Log_Of_N : constant Long_Float := Log (Long_Float (N), 2.0);
begin
if N = 1 then
return True;
end if;
while True loop
B := Log_Of_N / Log (Long_Float (A), 2.0);
if Is_Almost_Equal (B, Long_Float (Integer (B)))
and then Integer (B) > 1
then
return True;
end if;
exit when A * A > N;
A := @ + 1;
end loop;
return False;
end Is_Power;
-- An Achilles number is a powerful number that can't be expressed
-- as a power
function Is_Achilles (N : Integer) return Boolean is
begin
if Is_Powerful (N) then
if Is_Power (N) = False then
return True;
end if;
end if;
return False;
end Is_Achilles;
-- Calculates the Euler totient of a number
function Totient (N : Integer) return Integer is
Tot : Integer := N;
I : Integer;
N2 : Integer := N;
begin
I := 2;
while I * I <= N2 loop
if N2 mod I = 0 then
while N2 mod I = 0 loop
N2 := N2 / I;
end loop;
Tot := Tot - Tot / I;
end if;
if I = 2 then
I := 1;
end if;
I := I + 2;
end loop;
if N2 > 1 then
Tot := Tot - Tot / N2;
end if;
return Tot;
end Totient;
-- A Strong Achilles number is an Achilles number whose Euler Totient
-- is also an Achilles number
function Is_Strong_Achilles (N : Integer) return Boolean is
begin
if Is_Achilles (N) then
if Is_Achilles (Totient (N)) then
return True;
end if;
end if;
return False;
end Is_Strong_Achilles;
-- Counts the digits in a number by taking the string from
-- its 'Image attribute, trimming it and counting the characters
function Count_Digits (N : Integer) return Natural is
Integer_Str : constant String := Trim (N'Image, Both);
begin
return Integer_Str'Length;
end Count_Digits;
begin
-- Find the first 50 Achilles numbers
declare
N : Integer := 1;
Count : Integer := 1;
begin
Ada.Text_IO.Put_Line ("First 50 Achilles numbers:");
while Count <= 50 loop
if Is_Achilles (N) then
Count := @ + 1;
Ada.Text_IO.Put (N'Image & " ");
end if;
N := @ + 1;
end loop;
Ada.Text_IO.New_Line;
end;
-- Find the first 20 Strong Achilles numbers
declare
N : Integer := 1;
Count : Integer := 1;
begin
Ada.Text_IO.Put_Line ("First 20 Strong Achilles numbers:");
while Count <= 20 loop
if Is_Strong_Achilles (N) then
Count := @ + 1;
Ada.Text_IO.Put (N'Image & " ");
end if;
N := @ + 1;
end loop;
Ada.Text_IO.New_Line;
end;
-- Count numbers with digits
declare
Counts : array (2 .. 6) of Natural := [others => 0];
N : Integer := 1;
begin
Ada.Text_IO.Put_Line ("Number of Achilles numbers with:");
while Count_Digits (N) <= Counts'Last loop
-- Ada.Text_IO.Put_Line ("Testing: " & N'Image);
if Is_Achilles (N) then
Counts (Count_Digits (N)) := @ + 1;
end if;
N := @ + 1;
end loop;
for I in Counts'Range loop
Ada.Text_IO.Put_Line (I'Image & " digits: " & Counts (I)'Image);
end loop;
end;
end Achilles_Numbers;

View file

@ -0,0 +1,16 @@
function Ackermann(m,n: integer): integer;
begin
if (m < 0) or (n < 0) then
raise new System.ArgumentOutOfRangeException();
if m = 0 then
Result := n + 1
else if n = 0 then
Result := Ackermann(m - 1, 1)
else Result := Ackermann(m - 1, Ackermann(m, n - 1))
end;
begin
for var m := 0 to 3 do
for var n := 0 to 4 do
Println($'Ackermann({m}, {n}) = {Ackermann(m,n)}');
end.

View file

@ -0,0 +1,34 @@
#include <cstdint>
#include <iostream>
#include <map>
#include <string>
class Demonstration {
public:
Demonstration() {
variables = { };
}
std::map<std::string, double> variables;
};
int main() {
Demonstration demo;
std::cout << "Create two variables at runtime:" << std::endl;
for ( uint32_t i = 1; i <= 2; ++i ) {
std::cout << " Variable number " << i << ":" << std::endl;
std::cout << " Enter name: " << std::endl;
std::string name;
std::cin >> name;
std::cout << " Enter value: " << std::endl;
double value;
std::cin >> value;
demo.variables[name] = value;
}
std::cout << std::endl;
std::cout << "Two new runtime variables appear to have been created." << std::endl;
for ( const auto &[key, value] : demo.variables ) {
std::cout << "Variable " << key << " = " << value << std::endl;
}
}

View file

@ -0,0 +1,19 @@
type
MyClass = class
private
dict := new Dictionary<string,object>;
public
procedure Add(name: string; value: object) := dict[name] := value;
property Items[name: string]: object read dict[name]; default;
end;
begin
var obj := new MyClass;
obj.Add('Name','PascalABC.NET');
obj.Add('Age',16);
Println(obj['Name'],obj['Age']);
var obj1 := new MyClass;
obj1.Add('X',2.3);
obj1.Add('Y',3.8);
Println(obj1['X'],obj1['Y']);
end.

View file

@ -20,5 +20,6 @@ BEGIN # find additive primes - primes whose digit sum is also prime #
FI
FI
OD;
print( ( newline, "Found ", whole( additive count, 0 ), " additive primes below ", whole( UPB prime + 1, 0 ), newline ) )
print( ( newline, "Found ", whole( additive count, 0 ) ) );
print( ( " additive primes below ", whole( UPB prime + 1, 0 ), newline ) )
END

View file

@ -0,0 +1,86 @@
internal class Program
{
private static void Main(string[] args)
{
long primeCandidate = 1;
long additivePrimeCount = 0;
Console.WriteLine("Additive Primes");
while (primeCandidate < 500)
{
if (IsAdditivePrime(primeCandidate))
{
additivePrimeCount++;
Console.Write($"{primeCandidate,-3} ");
if (additivePrimeCount % 10 == 0)
{
Console.WriteLine();
}
}
primeCandidate++;
}
Console.WriteLine();
Console.WriteLine($"Found {additivePrimeCount} additive primes less than 500");
}
private static bool IsAdditivePrime(long number)
{
if (IsPrime(number) && IsPrime(DigitSum(number)))
{
return true;
}
return false;
}
private static bool IsPrime(long number)
{
if (number < 2)
{
return false;
}
if (number % 2 == 0)
{
return number == 2;
}
if (number % 3 == 0)
{
return number == 3;
}
int delta = 2;
long k = 5;
while (k * k <= number)
{
if (number % k == 0)
{
return false;
}
k += delta;
delta = 6 - delta;
}
return true;
}
private static long DigitSum(long n)
{
long sum = 0;
while (n > 0)
{
sum += n % 10;
n /= 10;
}
return sum;
}
}

View file

@ -1,18 +1,20 @@
val .isPrime = fn(.i) .i == 2 or .i > 2 and
not any fn(.x) .i div .x, pseries 2 .. .i ^/ 2
val isPrime = fn(i) {
i == 2 or i > 2 and
not any(fn x: i div x, pseries(2 .. i ^/ 2))
}
val .sumDigits = fn(.i) fold fn{+}, s2n string .i
val sumDigits = fn i: fold(fn{+}, s2n(string(i)))
writeln "Additive primes less than 500:"
var .count = 0
var cnt = 0
for .i in [2] ~ series(3..500, 2) {
if .isPrime(.i) and .isPrime(.sumDigits(.i)) {
write $"\{.i:3} "
.count += 1
if .count div 10: writeln()
for i in [2] ~ series(3..500, 2) {
if isPrime(i) and isPrime(sumDigits(i)) {
write "{{i:3}} "
cnt += 1
if cnt div 10: writeln()
}
}
writeln $"\n\n\{.count} additive primes found.\n"
writeln "\n\n{{cnt}} additive primes found.\n"

View file

@ -0,0 +1,44 @@
MODULE AdditivePrimes EXPORTS Main;
IMPORT SIO,Fmt;
CONST
Max = 500;
VAR
Count:CARDINAL := 0;
Prime:ARRAY[2..Max] OF BOOLEAN;
PROCEDURE DigitSum(N:CARDINAL):CARDINAL =
BEGIN
IF N < 10 THEN RETURN N
ELSE RETURN (N MOD 10) + DigitSum(N DIV 10) END;
END DigitSum;
PROCEDURE Sieve() =
VAR J:CARDINAL;
BEGIN
FOR I := 2 TO Max DO Prime[I] := TRUE END;
FOR I := 2 TO Max DIV 2 DO
IF Prime[I] THEN
J := I*2;
WHILE J <= Max DO
Prime[J] := FALSE;
INC(J,I)
END
END
END;
END Sieve;
BEGIN
Sieve();
FOR N := 2 TO Max DO
IF Prime[N] AND Prime[DigitSum(N)] THEN
SIO.PutText(Fmt.F("%4s",Fmt.Int(N)));
INC(Count);
IF Count MOD 10 = 0 THEN SIO.Nl() END
END
END;
SIO.PutText(Fmt.F("\nThere are %s additive primes less than %s.\n",
Fmt.Int(Count),Fmt.Int(Max)));
END AdditivePrimes.

View file

@ -0,0 +1,6 @@
begin
var i: integer := 3;
var p: ^integer := @i;
p^ += 2;
Print(p^,i);
end.

View file

@ -0,0 +1,17 @@
# Split the text at $ and then justify each word 3 ways
N ← {"Given$a$text$file$of$many$lines,$where$fields$within$a$line$"
"are$delineated$by$a$single$'dollar'$character,$write$a$program"
"that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$"
"column$are$separated$by$at$least$one$space."
"Further,$allow$for$each$word$in$a$column$to$be$either$left$"
"justified,$right$justified,$or$center$justified$within$its$column."}
Ls ← ≡⍚(⊜□≠@$.)N # Get the word arrays
P ← +1/↥≡◇⧻/◇⊂Ls # Padding = Max length + 1
PadL ← /↥⬚@ ⊟↯P@
PadR ← ⍜⇌PadL
PadC ← PadL⊂↯:@ ⌊÷2-:P⧻.
Format! ← ≡&p≡(□/⊂≡◇^!°□)
# Demonstration of use of an array macro, which actually just resolves to
# ⊃(Format!PadC|Format!PadR|Format!PadL)Ls
Fall‼! ←^ $"⊃(_)"/⊂≡($"Format!_ |"°□)⇌
Fall‼!PadL PadR PadC Ls

View file

@ -30,3 +30,6 @@ Show all output on this page.
* &nbsp; [[Amicable pairs]]
<br><br>
;External links:
* [https://www.youtube.com/watch?v=OtYKDzXwDEE An amazing thing about 276], Numberphile

View file

@ -1,15 +1,15 @@
val .wordsets = [
val wordsets = [
fw/the that a/,
fw/frog elephant thing/,
fw/walked treaded grows/,
fw/slowly quickly/,
]
val .alljoin = fn(.words) for[=true] .i of len(.words)-1 {
if last(.words[.i]) != first(.words[.i+1]): break = false
val alljoin = fn words: for[=true] i of len(words)-1 {
if words[i][-1] != words[i+1][1]: break = false
}
# .amb expects 2 or more arguments
val .amb = fn(...[2 .. -1] .words) if(.alljoin(.words): join " ", .words)
# amb expects 2 or more arguments
val amb = fn ...[2..] words: if alljoin(words) { join " ", words }
writeln join "\n", filter mapX .amb, .wordsets...
writeln join("\n", filter(mapX(amb, wordsets...)))

View file

@ -0,0 +1,87 @@
(defun code-letters (str)
"Sort STR into alphabetized list of individual letters."
(sort (split-string str "" t) #'string<))
(defun code-letters-to-string (str)
"Sort STR alphabetically and combine into one string."
(apply #'concat (code-letters str)))
(defun remove-periods (str)
"Remove periods (full stops) from STR."
(string-replace "." "" str))
(defun list-pair (str)
"Create paired list from STR, STR (unchanged) and alphabetized order of STR."
;; Remove periods from alphabetized order to make regex matching easier
(let ((letter-list (remove-periods (code-letters-to-string str))))
(list letter-list str)))
(defun pair-up (words)
"Make list of lists of paired words, one alphabetized one original."
(let ((paired-list)
(temp-pair))
(dolist (word words)
(setq temp-pair (list-pair word))
(push temp-pair paired-list))
paired-list))
(defun create-list-of-numbers (my-list)
"Create list of numbers from MY-LIST."
(let ((list-of-numbers))
(dolist (one-pair my-list)
(push (car one-pair) list-of-numbers))
list-of-numbers))
(defun get-largest-number (my-list)
"Find largest number in MY-LIST."
(let ((list-of-numbers))
(setq list-of-numbers (create-list-of-numbers my-list))
(apply #'max list-of-numbers)))
(defun make-list-matching-words (coded-word-and-original number-and-code-pair)
"List original words whose code matches code in NUMBER-AND-CODE-PAIR."
(dolist (word-pair coded-word-and-original)
;; test if coded word in CODED-WORD-AND-ORIGINAL matches
;; coded word in NUMBER-AND-CODE-PAIR
(when (string= (nth 0 word-pair) (nth 1 number-and-code-pair))
;; insert the original word
(insert (format "%s " (nth 1 word-pair)))))
(insert "\n"))
(defun count-anagrams ()
"Count the number of anagrams in file wordlist.txt"
(let ((coded-word-and-original)
(just-coded-words)
(unique-coded-words)
(count-and-code)
(number-of-anagrams)
(largest-number))
;; Path below needs to be adapted to individual case
(find-file "~/Documents/Elisp/wordlist.txt")
(beginning-of-buffer)
;; create list of lists of coded words and originals
(setq coded-word-and-original (pair-up (split-string (buffer-string) "\n")))
(find-file "temp-all-coded")
(erase-buffer)
(dolist (number-and-code-pair coded-word-and-original)
;; make list of just the coded words
(push (nth 0 number-and-code-pair) just-coded-words))
(dolist (one-word just-coded-words)
;; write list of coded words to buffer for later processing
(insert (format "%s\n" one-word)))
;; create a list of coded words with no repetitions
(setq unique-coded-words (seq-uniq just-coded-words))
(dolist (one-code unique-coded-words)
(find-file "temp-all-coded")
(beginning-of-buffer)
;; count the number of times ONE-CODE appears in buffer
(setq number-of-anagrams (how-many (format "^%s$" one-code)))
(if (>= number-of-anagrams 1) ; eliminate "words" of zero length
(push (list number-of-anagrams one-code) count-and-code)))
(find-file "anagram-listing")
(erase-buffer)
(setq largest-number (get-largest-number count-and-code))
(dolist (number-and-code-pair count-and-code)
;; when the number in NUMBER-AND-CODE-PAIR = largest number of anagrams
(when (= (nth 0 number-and-code-pair) largest-number)
(make-list-matching-words coded-word-and-original number-and-code-pair)))))

View file

@ -0,0 +1,74 @@
(defun code-letters (str)
"Sort STR into alphabetized list of individual letters."
(sort (split-string str "" t) #'string<))
(defun code-letters-to-string (str)
"Sort STR alphabetically and combine into one string."
(apply #'concat (code-letters str)))
(defun add-to-hash (key value table)
"If KEY exists, add VALUE to list of values.
If KEY does not exist, associate value with KEY."
(let ((current-values))
(if (gethash key table)
(progn
(setq current-values (gethash key table))
(setq current-values (push value current-values))
(puthash key current-values table))
(puthash key (list value) table))))
(defun create-list-of-numbers (hash-table)
"Create a list of numbers from HASH-TABLE."
(let ((current-number)
(list-of-numbers))
(setq list-of-numbers (list)) ; omit?
(maphash (lambda (key value)
(setq current-number (car (gethash key hash-table)))
(push current-number list-of-numbers))
hash-table)
list-of-numbers))
(defun find-largest-number-in-hash (hash-table)
"Find largest number in HASH-TABLE."
(let ((list-of-numbers))
(setq list-of-numbers (create-list-of-numbers hash-table))
(apply #'max list-of-numbers)))
(defun find-longest-lists-of-anagrams (&optional file)
"Find the set(s) of largest number of anagrams in file wordlist.txt"
(let ((largest-number)
(hash-key)
(dictionary-table (make-hash-table :test 'equal)))
;; Path and filename below needs to be adapted to individual case if
;; FILE is *not* passed to this function
(with-temp-buffer
(insert-file-contents (or file "~/Documents/Elisp/wordlist.txt"))
(beginning-of-buffer)
;; set up hash table with key and word(s)
;; key = letters of word, but with letters in
;; alphabetical order. Create list word(s) associated
;; with key.
(dolist (current-word (split-string (buffer-string) "\n"))
(setq hash-key (code-letters-to-string current-word))
(add-to-hash hash-key current-word dictionary-table))
;; Count number of anagram words
(maphash (lambda (key value)
"Add number of anagram words to VALUE."
(add-to-hash key (length (gethash key dictionary-table)) dictionary-table))
dictionary-table)
;; find the size of the largest list(s) of anagrams
(setq largest-number (find-largest-number-in-hash dictionary-table)))
;; set up empty buffer to show results
(with-current-buffer (pop-to-buffer "anagram-listing")
(erase-buffer)
;; show results
(maphash (lambda (key value)
"Display longest lists of anagrams."
(when (= largest-number (car (gethash key dictionary-table)))
(mapc
(lambda (element)
"Insert ELEMENT followed by one space in buffer."
(insert (format "%s " element)))
(cdr (gethash key dictionary-table)))
(insert "\n")))
dictionary-table))))

View file

@ -0,0 +1,7 @@
begin
var s := System.Net.WebClient.Create.DownloadString('http://wiki.puzzlers.org/pub/wordlists/unixdict.txt');
var words := s.Split;
var groups := words.GroupBy(word -> word.Order.JoinToString);
var maxCount := groups.Max(gr -> gr.Count);
groups.Where(gr -> gr.Count = maxCount).PrintLines;
end.

View file

@ -0,0 +1,13 @@
function Fib(n: integer): integer;
begin
if n <= 0 then
raise new System.ArgumentOutOfRangeException('Must be > 0','n');
var fibHelper: (integer,integer,integer) -> integer;
fibHelper := (n,a,b) -> n = 1 ? a : fibHelper(n-1, b, a + b);
Result := fibHelper(n,1,1);
end;
begin
for var i:=1 to 10 do
Fib(i).Print;
end.

View file

@ -0,0 +1,13 @@
function Fib(n: integer): integer;
function fibHelper(n,a,b: integer): integer :=
n = 1 ? a : fibHelper(n-1, b, a + b);
begin
if n <= 0 then
raise new System.ArgumentOutOfRangeException('Must be > 0','n');
Result := fibHelper(n,1,1);
end;
begin
for var i:=1 to 10 do
Fib(i).Print;
end.

View file

@ -1,18 +1,18 @@
val .countDivisors = fn(.n) {
if .n < 2: return 1
for[=2] .i = 2; .i <= .n\2; .i += 1 {
if .n div .i : _for += 1
val countDivisors = fn(n) {
if n < 2: return 1
for[=2] i = 2; i <= n\2; i += 1 {
if n div i: _for += 1
}
}
writeln "The first 20 anti-primes are:"
var .maxDiv, .count = 0, 0
for .n = 1; .count < 20; .n += 1 {
val .d = .countDivisors(.n)
if .d > .maxDiv {
write .n, " "
.maxDiv = .d
.count += 1
var maxDiv, cnt = 0, 0
for n = 1; cnt < 20; n += 1 {
val d = countDivisors(n)
if d > maxDiv {
write n, " "
maxDiv = d
cnt += 1
}
}
writeln()

View file

@ -0,0 +1,8 @@
# slightly faster than the simplistic /+=0◿+1⇡.
NDivs ← ⟨+2/+=0◿(↘1+1⇡⌊÷2).|1⟩<2.
⇌⊙◌◌⍢(
# Inc n, get NDiv: if >m, join n to accum, store new m.
⟨◌|⟜(⊂⊢)⍜(⊡1|◌):⟩:⟜<NDivs°⊟.⍜⊢(+1)
|
⋅(<:⧻) # Repeat until we have enough values.
)0_0 [] 20 # [n m] [accum] limit

View file

@ -1 +1 @@
writeln map fn{^2}, 1..10
writeln map(fn{^2}, 1..10)

View file

@ -0,0 +1,5 @@
begin
var a := Arr(1..10);
a := a.Select(x -> x * x).ToArray;
a.ForEach(x -> Print(x));
end.

View file

@ -0,0 +1,20 @@
func aeq a b .
return if abs (a - b) <= abs a * 1e-14
.
proc test a b . .
write a & " " & b & " -> "
if aeq a b = 1
print "true"
else
print "false"
.
.
numfmt 10 0
test 100000000000000.01 100000000000000.011
test 100.01 100.011
test 10000000000000.001 / 10000 1000000000.0000001
test 0.001 0.0010000001
test 1.01e-22 0
test sqrt 2 * sqrt 2 2
test -sqrt 2 * sqrt 2 -2
test 3.14159265358979323846 3.14159265358979324

View file

@ -0,0 +1,64 @@
/*
Uses GMP for Multiple Precision Arithmetic
Install GMP using terminal and Homebrew command, "brew install gmp"
before running this app in FutureBasic.
Homebrew available here, https://brew.sh
*/
include "NSLog.incl"
void local fn GMPoutput
CFStringRef sourcePath = fn StringByAppendingPathComponent( @"/tmp/", @"temp.m" )
CFStringRef executablePath = fn StringByAppendingPathComponent( @"/tmp/", @"temp" )
CFStringRef gmpStr = @"#import <Foundation/Foundation.h>\n#import <gmp.h>\n¬
int main(int argc, const char * argv[]) {\n¬
@autoreleasepool {\n¬
mpz_t a;\n¬
mpz_init_set_ui(a, 5);\n¬
mpz_pow_ui(a, a, 1 << 18);\n¬
size_t len = mpz_sizeinbase(a, 10);\n¬
printf(\"GMP says size is: %zu\\n\", len);\n¬
char *s = mpz_get_str(0, 10, a);\n¬
size_t trueLen = strlen(s);\n¬
printf(\" Actual size is: %zu\\n\", trueLen);\n¬
printf(\"First & Last 20 digits: %.20s…%s\\n\", s, s + trueLen - 20);\n¬
}\n¬
return 0;\n¬
}"
fn StringWriteToURL( gmpStr, fn URLFileURLWithPath( sourcePath ), YES, NSUTF8StringEncoding, NULL )
TaskRef task = fn TaskInit
TaskSetExecutableURL( task, fn URLFileURLWithPath( @"usr/bin/clang" ) )
CFArrayRef arguments = @[@"-o", executablePath, sourcePath, @"-lgmp", @"-fobjc-arc"]
TaskSetArguments( task, arguments )
PipeRef pipe = fn PipeInit
TaskSetStandardInput( task, pipe )
fn TaskLaunch( task, NULL )
TaskWaitUntilExit( task )
if ( fn TaskTerminationStatus( task ) == 0 )
TaskRef executionTask = fn TaskInit
TaskSetExecutableURL( executionTask, fn URLFileURLWithPath( executablePath ) )
PipeRef executionPipe = fn PipeInit
TaskSetStandardOutput( executionTask, executionPipe )
FileHandleRef executionFileHandle = fn PipeFileHandleForReading( executionPipe )
fn TaskLaunch( executionTask, NULL )
TaskWaitUntilExit( executionTask )
CFDataRef outputData = fn FileHandleReadDataToEndOfFile( executionFileHandle, NULL )
CFStringRef outputStr = fn StringWithData( outputData, NSUTF8StringEncoding )
NSLog( @"%@", outputStr )
else
alert 1,, @"GMP required but not installed"
end if
fn FileManagerRemoveItemAtURL( fn URLFileURLWithPath( sourcePath ) )
fn FileManagerRemoveItemAtURL( fn URLFileURLWithPath( executablePath ) )
end fn
fn GMPoutput
HandleEvents

View file

@ -1,9 +1,9 @@
val .xs = string 5 ^ 4 ^ 3 ^ 2
val xs = string(5 ^ 4 ^ 3 ^ 2)
val .len = len .xs
writeln .len, " digits"
writeln len(xs), " digits"
if len(xs) > 39 and s2s(xs, 1..20) == "62060698786608744707" and
s2s(xs, -20 .. -1) == "92256259918212890625" {
if .len > 39 and s2s(.xs, 1..20) == "62060698786608744707" and
s2s(.xs, .len-19 .. .len) == "92256259918212890625" {
writeln "SUCCESS"
}

View file

@ -0,0 +1,19 @@
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
public final class ArenaStoragePool {
public static void main(String[] args) {
List<Object> storagePool = new ArrayList<Object>();
storagePool.addLast(42);
storagePool.addLast("Hello World");
storagePool.addFirst(BigInteger.ZERO);
System.out.println(storagePool);
storagePool = null;
System.gc();
}
}

View file

@ -0,0 +1,19 @@
func[] add a[] b[] .
return [ a[1] + b[1] a[2] + b[2] ]
.
func[] mult a[] b[] .
return [ a[1] * b[1] - a[2] * b[2] a[1] * b[2] + a[2] * b[1] ]
.
func[] inv a[] .
denom = a[1] * a[1] + a[2] * a[2]
return [ a[1] / denom (-a[2] / denom) ]
.
func[] neg a[] .
return [ -a[1] (-a[2]) ]
.
a[] = [ 1 1 ]
b[] = [ pi 1.2 ]
print add a[] b[]
print mult a[] b[]
print neg a[]
print inv a[]

View file

@ -0,0 +1,14 @@
begin
var a := Cplx(1,2);
var b := Cplx(3,4);
Println(a + b);
Println(a - b);
Println(a * b);
Println(a / b);
Println(-a);
Println(1/a);
Println(a.Real,a.Imaginary);
Println(a.Conjugate);
Println(Abs(a));
Println(a ** b);
end.

View file

@ -23,7 +23,6 @@ fun main = int by List args
writeLine("integer quotient: " + (a / b)) # truncates towards 0
writeLine("remainder: " + (a % b)) # matches sign of first operand
writeLine("exponentiation: " + (a ** b))
writeLine("logarithm: " + (a // b))
writeLine("divmod: " + divmod(a, b))
return 0
end

View file

@ -0,0 +1,10 @@
begin
var (a,b) := ReadInteger2;
Println($'{a} + {b} = {a + b}');
Println($'{a} - {b} = {a - b}');
Println($'{a} * {b} = {a * b}');
Println($'{a} / {b} = {a / b}');
Println($'{a} div {b} = {a div b}');
Println($'{a} mod {b} = {a mod b}');
Println($'{a} ** {b} = {a ** b}');
end.

View file

@ -0,0 +1,31 @@
library(gmp) #for big number factorization
arithmetic_derivative<-function(x){
if (x==0|x==1|x==-1){
D=0
}
else{
n=ifelse(x<0,-x,x)
prime_decomposition <-as.numeric(factorize(n))
if (length(prime_decomposition)==1){
D<- 1
}
else{
D<-sum(prime_decomposition[c(1,2)])
if (length(prime_decomposition)>2){
cumulative_prod <-cumprod(prime_decomposition)
for (i in 3:length(prime_decomposition)){
D<- D * prime_decomposition[i] + cumulative_prod[i-1]
}
}
}
}
sign(x)*D
}
print(t(matrix(sapply(-99:100,arithmetic_derivative),nrow=10)))
for (k in 1:20){
x <- 10**k
cat(paste0("D(",x,")/7 = ",arithmetic_derivative(x)/7,"\n"),sep = "")}

View file

@ -0,0 +1,34 @@
-- Use the Arithmetic-geometric mean to calculate Pi
-- J. Carter 2024 May
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Text_IO;
with System;
procedure AGM_Pi is
type Real is digits System.Max_Digits;
package Math is new Ada.Numerics.Generic_Elementary_Functions (Float_Type => Real);
A : Real := 1.0;
B : Real := Math.Sqrt (0.5);
T : Real := 0.25;
N : Real := 1.0;
Prev_A : Real;
Pi : Real;
Prev_Pi : Real := 0.0;
begin -- AGM_Pi
Calculate : loop
Prev_A := A;
A := (A + B) / 2.0;
B := Math.Sqrt (Prev_A * B);
T := T - N * (A - Prev_A) ** 2;
N := N + N;
Pi := (A + B) ** 2 / (4.0 * T);
Ada.Text_IO.Put_Line (Item => Pi'Image);
exit Calculate when abs (Prev_Pi - Pi) < 10.0 ** (-(Real'Digits - 1) );
Prev_Pi := Pi;
end loop Calculate;
end AGM_Pi;

View file

@ -0,0 +1,3 @@
# Calculate the arithmetic-geometric mean
Agm ← ⊙◌◌⍢(⊃(√×|÷2+)|<⌵-)
Agm 1 ÷:1√2 0.0000001

View file

@ -1,4 +1,4 @@
val .a = [1, 2, 3]
val .b = [7, 8, 9]
val .c = .a ~ .b
writeln .c
val a = [1, 2, 3]
val b = [7, 8, 9]
val c = a ~ b
writeln c

View file

@ -0,0 +1,5 @@
##
var a := |1,2,3,4|;
var b := Arr(5..8);
var c := a + b;
c.Println;

View file

@ -0,0 +1 @@
⊂[1 2 3] [4 5 6]

View file

@ -0,0 +1,4 @@
// Array length. Mikhalkovich Stanislav: May 16, 2024
##
var a := |'apple','orange'|;
a.Length.Print;

View file

@ -0,0 +1 @@
⧻{"apple" "orange"}

View file

@ -1,9 +1,10 @@
procedure Array_Test is
A, B : array (1..20) of Integer;
type Example_Array_Type is array (1..20) of Integer;
A, B : Example_Array_Type;
-- Ada array indices may begin at any value, not just 0 or 1
C : array (-37..20) of integer
C : array (-37..20) of Integer;
-- Ada arrays may be indexed by enumerated types, which are
-- discrete non-numeric types
@ -26,7 +27,7 @@ procedure Array_Test is
Const : constant Arr := (1 .. 10 => 1, 11 .. 20 => 2, 21 | 22 => 3);
Centered : Arr (-50..50) := (0 => 1, Others => 0);
Result : Integer
Result : Integer;
begin
A := (others => 0); -- Assign whole array
@ -37,7 +38,7 @@ begin
A (3..5) := (2, 4, -1); -- Assign a constant slice
A (3..5) := A (4..6); -- It is OK to overlap slices when assigned
Fingers_Extended'First := False; -- Set first element of array
Fingers_Extended'Last := False; -- Set last element of array
Fingers_Extended(Fingers'First) := False; -- Set first element of array
Fingers_Extended(Fingers'Last) := False; -- Set last element of array
end Array_Test;

View file

@ -1,24 +1,24 @@
var .a1 = [1, 2, 3, "abc"]
val .a2 = series 4..10
val .a3 = .a1 ~ .a2
var a1 = [1, 2, 3, "abc"]
val a2 = series(4..10)
val a3 = a1 ~ a2
writeln "initial values ..."
writeln ".a1: ", .a1
writeln ".a2: ", .a2
writeln ".a3: ", .a3
writeln "a1: ", a1
writeln "a2: ", a2
writeln "a3: ", a3
writeln()
.a1[4] = .a2[4]
writeln "after setting .a1[4] = .a2[4] ..."
writeln ".a1: ", .a1
writeln ".a2: ", .a2
writeln ".a3: ", .a3
a1[4] = a2[4]
writeln "after setting a1[4] = a2[4] ..."
writeln "a1: ", a1
writeln "a2: ", a2
writeln "a3: ", a3
writeln()
writeln ".a2[1]: ", .a2[1]
writeln "a2[1]: ", a2[1]
writeln()
writeln "using index alternate ..."
writeln ".a2[5; 0]: ", .a2[5; 0]
writeln ".a2[10; 0]: ", .a2[10; 0]
writeln "a2[5; 0]: ", a2[5; 0]
writeln "a2[10; 0]: ", a2[10; 0]
writeln()

View file

@ -0,0 +1,19 @@
begin
// Static old-style arrays
var a: array [1..3] of integer := (1,2,3);
Println(a[1]);
// dynamic arrays - zero based indices
var a1: array of integer := new integer[3](1,3,5);
Println(a1[0]);
// dynamic arrays
var a2 := |1,3,5|; // literal array
SetLength(a2,4);
a2[^1] := 7; // "push" new value; ^1 - the first element from the end
// Lists are dynamically resizing arrays
var lst := new List<integer>(a1);
lst.Add(7);
Println(lst[^1]);
end.

View file

@ -0,0 +1,62 @@
pragma Ada_2022;
with Ada.Text_IO;
with Ada.Containers.Vectors;
with Fifo;
procedure Ascending_Primes is
subtype Prime is Positive range 2 .. Positive'Last with
Dynamic_Predicate =>
(for all I in 2 .. (Prime / 2) => (Prime mod I) /= 0);
package Prime_Vectors is new
Ada.Containers.Vectors
(Index_Type => Natural,
Element_Type => Prime);
package Positive_Fifo is new Fifo (Positive);
use Positive_Fifo;
-- Helper queue and vector for primes found
Queue : Fifo_Type;
Primes : Prime_Vectors.Vector;
begin
-- Initialise the queue with the first nine numbers
for Index in 1 .. 9 loop
Queue.Push (Index);
end loop;
-- Read the canditate numbers from the queue
-- check if they are prime and generate
-- the next possible candidates from them
while not Queue.Is_Empty loop
declare
Candidate : Positive;
Next_Digit : Positive;
begin
Queue.Pop (Candidate);
if Candidate in Prime then
Primes.Append (Candidate);
end if;
-- Generate the next possible candidates
-- from the current one
Next_Digit := Candidate mod 10 + 1;
while Next_Digit <= 9 loop
Queue.Push (Candidate * 10 + Next_Digit);
Next_Digit := @ + 1;
end loop;
end;
end loop;
-- Print the final list of prime numbers
for P of Primes loop
Ada.Text_IO.Put (P'Image);
end loop;
Ada.Text_IO.New_Line;
end Ascending_Primes;

View file

@ -0,0 +1,2 @@
/◇⊂{⍥(/◇⊂≡(□+×10:↘+1◿10,⇡10).)8 +1⇡9} # Build ascending numbers.
⊏⊸⍏▽⊸≡(=1⧻°/×) # Find primes and sort.

View file

@ -0,0 +1,6 @@
module test {
void run() {
Int x = 7;
assert x == 42;
}
}

View file

@ -0,0 +1,5 @@
begin
var a := 3;
Assert(a = 3);
Assert(a = 4, 'Bad assert!');
end.

View file

@ -1,12 +1,12 @@
var .hash = h{1: "abc", "1": 789}
var h = {1: "abc", "1": 789}
# may assign with existing or non-existing hash key (if hash is mutable)
.hash[7] = 49
h[7] = 49
writeln .hash[1]
writeln .hash[7]
writeln .hash["1"]
writeln h[1]
writeln h[7]
writeln h["1"]
# using an alternate value in case of invalid index; prevents exception
writeln .hash[1; 42]
writeln .hash[2; 42]
writeln h[1; 42]
writeln h[2; 42]

View file

@ -0,0 +1,7 @@
begin
var zoo := new Dictionary<string,integer>;
zoo['crocodile'] := 2;
zoo['jiraffe'] := 3;
zoo['behemoth'] := 1;
zoo.Println;
end.

View file

@ -0,0 +1,11 @@
begin
var zoo := new Dictionary<string,integer>;
zoo['crocodile'] := 2;
zoo['jiraffe'] := 3;
zoo['behemoth'] := 1;
foreach var kv in zoo do
Println(kv.Key, kv.Value);
Println;
foreach var key in zoo.Keys do
Println(key,zoo[key]);
end.

View file

@ -1,4 +1,4 @@
val .mean = fn(.x) fold(fn{+}, .x) / len(.x)
val umean = fn x:fold(fn{+}, x) / len(x)
writeln " custom: ", .mean([7, 3, 12])
writeln " custom: ", umean([7, 3, 12])
writeln "built-in: ", mean([7, 3, 12])

View file

@ -0,0 +1,24 @@
# Find mean time of day using 'mean angle'
ParseTS ← setinv(/(+×60)⊜⋕≠@:.|/(◇⊂◇⊂)@:≡(□↙¯2⊂"00"°⋕)⌊[⍥(⊃÷◿60)2])
RpS ← ×π÷180÷240 1 # Radians per second
SpD ← ×× 24 60 60 # Seconds per day
Cos ← setinv(∿+η|-:η°∿)
# Polar to (complex) cartesian, and inverse.
PtoC ← setinv(
⍜⊟×⊃∿Cos:°⊟
| √+∩(×.),⟜:°ℂ
⍤("undefined for r=0")≠0.
⊟⟜(⍥¯<0:°Cos÷)
)
Ts ← "23:00:17, 23:40:20, 00:12:45, 00:17:19"
⊜(PtoC ⊟1 ×RpS ParseTS)¬⦷", ".Ts # Get TSs as unit complex numbers.
⁅÷RpS⊡1°PtoC÷⊃(⧻|/+) # Average them and convert back to seconds.
°ParseTS+×SpD<0. # Ensure its >0, format as TS.
</syntaxhighlight >
{{out}}
<pre>
"23:47:43"
</pre>

View file

@ -0,0 +1,30 @@
# The input should be a JSON object with a key named "period".
# The output is a JSON object with a key named "average" giving the SMA.
def sma($x):
def average:
.n as $n
| if $n == null or $n == 0 then . + {n: 1, average: $x}
else .average |= (. * $n + $x) / ($n + 1)
| .n += 1
end;
if . == null or (.period and .period < 1)
then "The initial call to sma/1 must specify the period properly" | error
elif .n and .n < 0 then "Invalid value of .n" | error
elif (.period | isinfinite) then average
elif .n == null or .n == 0 then . + {n: 1, average: $x, array: [$x]}
else .n as $n
| if $n < .period
then .array += [$x]
| .n += 1
else .array |= .[1:] + [$x]
end
| .average = (.array | (add/length))
end;
# Call sma($x) for the 11 numbers 0, 1, ... 10.
def example($period):
reduce range(0;11) as $x({period: $period}; sma($x))
| .average ;
example(11), example(infinite)

View file

@ -0,0 +1,162 @@
' The control points of a planar quadratic Bézier curve form a
' triangle--called the "control polygon"--that completely contains
' the curve. Furthermore, the rectangle formed by the minimum and
' maximum x and y values of the control polygon completely contain
' the polygon, and therefore also the curve.
'
' Thus a simple method for narrowing down where intersections might
' be is: subdivide both curves until you find "small enough" regions
' where these rectangles overlap.
#define Min(a, b) iif((a) < (b), (a), (b))
#define Max(a, b) iif((a) > (b), (a), (b))
' Note that these are all mutable as we need to pass by reference.
Type Punto
x As Double
y As Double
End Type
Type QuadSpline
c0 As Double
c1 As Double
c2 As Double ' Non-parametric spline
End Type
Type QuadCurve
x As QuadSpline
y As QuadSpline ' Planar parametric spline
End Type
' Subdivision by de Casteljau's algorithm
Sub subdivideQuadSpline(q As QuadSpline, t As Double, u As QuadSpline, v As QuadSpline)
Dim As Double s = 1.0 - t
Dim As Double c0 = q.c0
Dim As Double c1 = q.c1
Dim As Double c2 = q.c2
u.c0 = c0
v.c2 = c2
u.c1 = s * c0 + t * c1
v.c1 = s * c1 + t * c2
u.c2 = s * u.c1 + t * v.c1
v.c0 = u.c2
End Sub
Sub subdivideQuadCurve(q As QuadCurve, t As Double, u As QuadCurve, v As QuadCurve)
subdivideQuadSpline(q.x, t, u.x, v.x)
subdivideQuadSpline(q.y, t, u.y, v.y)
End Sub
' It is assumed that xa0 <= xa1, ya0 <= ya1, xb0 <= xb1, and yb0 <= yb1.
Function rectsOverlap(xa0 As Double, ya0 As Double, xa1 As Double, ya1 As Double, _
xb0 As Double, yb0 As Double, xb1 As Double, yb1 As Double) As Boolean
Return (xb0 <= xa1 And xa0 <= xb1 And yb0 <= ya1 And ya0 <= yb1)
End Function
Function max3(x As Double, y As Double, z As Double) As Double
Return Max(Max(x, y), z)
End Function
Function min3(x As Double, y As Double, z As Double) As Double
Return Min(Min(x, y), z)
End Function
' This accepts the point as an intersection if the boxes are small enough.
Sub testIntersect(p As QuadCurve, q As QuadCurve, tol As Double, _
Byref exclude As Boolean, Byref accept As Boolean, Byref intersect As Punto)
Dim As Double pxmin = min3(p.x.c0, p.x.c1, p.x.c2)
Dim As Double pymin = min3(p.y.c0, p.y.c1, p.y.c2)
Dim As Double pxmax = max3(p.x.c0, p.x.c1, p.x.c2)
Dim As Double pymax = max3(p.y.c0, p.y.c1, p.y.c2)
Dim As Double qxmin = min3(q.x.c0, q.x.c1, q.x.c2)
Dim As Double qymin = min3(q.y.c0, q.y.c1, q.y.c2)
Dim As Double qxmax = max3(q.x.c0, q.x.c1, q.x.c2)
Dim As Double qymax = max3(q.y.c0, q.y.c1, q.y.c2)
exclude = True
accept = False
If rectsOverlap(pxmin, pymin, pxmax, pymax, qxmin, qymin, qxmax, qymax) Then
exclude = False
Dim As Double xmin = Max(pxmin, qxmin)
Dim As Double xmax = Min(pxmax, qxmax)
Assert(xmax >= xmin)
If xmax - xmin <= tol Then
Dim As Double ymin = Max(pymin, qymin)
Dim As Double ymax = Min(pymax, qymax)
Assert(ymax >= ymin)
If ymax - ymin <= tol Then
accept = True
intersect.x = 0.5 * xmin + 0.5 * xmax
intersect.y = 0.5 * ymin + 0.5 * ymax
End If
End If
End If
End Sub
Function seemsToBeDuplicate(intersects() As Punto, icount As Integer, _
xy As Punto, spacing As Double) As Boolean
Dim As Boolean seemsToBeDup = False
Dim As Integer i = 0
While Not seemsToBeDup And i <> icount
Dim As Punto pt = intersects(i)
seemsToBeDup = Abs(pt.x - xy.x) < spacing And Abs(pt.y - xy.y) < spacing
i += 1
Wend
Return seemsToBeDup
End Function
Sub findIntersects(p As QuadCurve, q As QuadCurve, tol As Double, _
spacing As Double, intersects() As Punto)
Dim As Integer numIntersects = 0
Type workset
p As QuadCurve
q As QuadCurve
End Type
Dim As workset workload(64)
Dim As Integer numWorksets = 1
workload(0) = Type<workset>(p, q)
' Quit looking after having emptied the workload.
While numWorksets <> 0
Dim As workset work = workload(numWorksets-1)
numWorksets -= 1
Dim As Boolean exclude, accept
Dim As Punto intersect
testIntersect(work.p, work.q, tol, exclude, accept, intersect)
If accept Then
' To avoid detecting the same intersection twice, require some
' space between intersections.
If Not seemsToBeDuplicate(intersects(), numIntersects, intersect, spacing) Then
intersects(numIntersects) = intersect
numIntersects += 1
End If
Elseif Not exclude Then
Dim As QuadCurve p0, p1, q0, q1
subdivideQuadCurve(work.p, 0.5, p0, p1)
subdivideQuadCurve(work.q, 0.5, q0, q1)
workload(numWorksets) = Type<workset>(p0, q0)
numWorksets += 1
workload(numWorksets) = Type<workset>(p0, q1)
numWorksets += 1
workload(numWorksets) = Type<workset>(p1, q0)
numWorksets += 1
workload(numWorksets) = Type<workset>(p1, q1)
numWorksets += 1
End If
Wend
End Sub
Dim As QuadCurve p, q
p.x = Type<QuadSpline>(-1.0, 0.0, 1.0)
p.y = Type<QuadSpline>( 0.0, 10.0, 0.0)
q.x = Type<QuadSpline>( 2.0, -8.0, 2.0)
q.y = Type<QuadSpline>( 1.0, 2.0, 3.0)
Dim As Double tol = 0.0000001
Dim As Double spacing = tol * 10.0
Dim As Punto intersects(4)
findIntersects(p, q, tol, spacing, intersects())
For i As Integer = 0 To 3
Print "("; intersects(i).x; ", "; intersects(i).y; ")"
Next i
Sleep

View file

@ -0,0 +1,215 @@
' In this program, both of the curves are adaptively "flattened":
' that is, converted to a piecewise linear approximation. Then the
' problem is reduced to finding intersections of line segments.
'
' How efficient or inefficient the method is I will not try to answer.
' (And I do sometimes compute things "too often", although a really good
' optimizer might fix that.)
'
' I will use the symmetric power basis that was introduced by J. Sánchez-Reyes:
'
' J. Sánchez-Reyes, The symmetric analogue of the polynomial power
' basis, ACM Transactions on Graphics, vol 16 no 3, July 1997, page 319.
'
' J. Sánchez-Reyes, Applications of the polynomial s-power basis
' in geometry processing, ACM Transactions on Graphics, vol 19
' no 1, January 2000, page 35.
'
' Flattening a quadratic that is represented in this basis has a few
' advantages, which I will not go into here. */
Type bernstein_spline
b0 As Double
b1 As Double
b2 As Double
End Type
Type spower_spline
c0 As Double
c1 As Double
c2 As Double
End Type
Type spower_curve
x As spower_spline
y As spower_spline
End Type
' Convert a non-parametric spline from Bernstein basis to s-power.
Function bernstein_spline_to_spower(S As bernstein_spline) As spower_spline
Dim As spower_spline T
T.c0 = S.b0
T.c1 = (2 * S.b1) - S.b0 - S.b2
T.c2 = S.b2
Return T
End Function
' Compose (c0, c1, c2) with (t0, t1). This will map the portion [t0,t1] onto
' [0,1]. (To get these expressions, I did not use the general-degree methods
' described by Sánchez-Reyes, but instead used Maxima, some while ago.)
'
' This method is an alternative to de Casteljau subdivision, and can be done
' with the coefficients in any basis. Instead of breaking the spline into two
' pieces at a parameter value t, it gives you the portion lying between two
' parameter values. In general that requires two applications of de Casteljau
' subdivision. On the other hand, subdivision requires two applications of the
' following.
Function spower_spline_portion(S As spower_spline, t0 As Double, t1 As Double) As spower_spline
Dim As Double t0_t0 = t0 * t0
Dim As Double t0_t1 = t0 * t1
Dim As Double t1_t1 = t1 * t1
Dim As Double c2p1m0 = S.c2 + S.c1 - S.c0
Dim As spower_spline T
T.c0 = S.c0 + (c2p1m0 * t0) - (S.c1 * t0_t0)
T.c1 = (S.c1 * t1_t1) - (2 * S.c1 * t0_t1) + (S.c1 * t0_t0)
T.c2 = S.c0 + (c2p1m0 * t1) - (S.c1 * t1_t1)
Return T
End Function
Function spower_curve_portion(C As spower_curve, t0 As Double, t1 As Double) As spower_curve
Dim As spower_curve D
D.x = spower_spline_portion(C.x, t0, t1)
D.y = spower_spline_portion(C.y, t0, t1)
Return D
End Function
' Given a parametric curve, is it "flat enough" to have its quadratic
' terms removed?
Function flat_enough(C As spower_curve, tol As Double) As Boolean
' The degree-2 s-power polynomials are 1-t, t(1-t), t. We want to
' remove the terms in t(1-t). The maximum of t(1-t) is 1/4, reached
' at t=1/2. That accounts for the 1/8=0.125 in the following:
Dim As Double cx0 = C.x.c0
Dim As Double cx1 = C.x.c1
Dim As Double cx2 = C.x.c2
Dim As Double cy0 = C.y.c0
Dim As Double cy1 = C.y.c1
Dim As Double cy2 = C.y.c2
Dim As Double dx = cx2 - cx0
Dim As Double dy = cy2 - cy0
Dim As Double error_squared = 0.125 * ((cx1 * cx1) + (cy1 * cy1))
Dim As Double length_squared = (dx * dx) + (dy * dy)
Return (error_squared <= length_squared * tol * tol)
End Function
' Given two line segments, do they intersect? One solution to this problem is
' to use the implicitization method employed in the Maxima example, except to
' do it with linear instead of quadratic curves. That is what I do here, with
' the the roles of who gets implicitized alternated. If both ways you get as
' answer a parameter in [0,1], then the segments intersect.
Sub test_line_segment_intersection(ax0 As Double, ax1 As Double, _
ay0 As Double, ay1 As Double, bx0 As Double, bx1 As Double, _
by0 As Double, by1 As Double, Byref they_intersect As Boolean, _
Byref x As Double, Byref y As Double)
Dim As Double anumer = ((bx1 - bx0) * ay0 - (by1 - by0) * ax0 _
+ bx0 * by1 - bx1 * by0)
Dim As Double bnumer = -((ax1 - ax0) * by0 - (ay1 - ay0) * bx0 _
+ ax0 * ay1 - ax1 * ay0)
Dim As Double denom = ((ax1 - ax0) * (by1 - by0) _
- (ay1 - ay0) * (bx1 - bx0))
Dim As Double ta = anumer / denom ' Parameter of segment a.
Dim As Double tb = bnumer / denom ' Parameter of segment b.
they_intersect = (0 <= ta And ta <= 1 And 0 <= tb And tb <= 1)
If they_intersect Then
x = ((1 - ta) * ax0) + (ta * ax1)
y = ((1 - ta) * ay0) + (ta * ay1)
End If
End Sub
Function too_close(x As Double, y As Double, xs() As Double, ys() As Double, _
num_points As Integer, spacing As Double) As Boolean
Dim As Boolean tooclose = False
Dim As Integer i = 0
While Not tooclose And i <> num_points
tooclose = (Abs(x - xs(i)) < spacing And Abs(y - ys(i)) < spacing)
i += 1
Wend
Return tooclose
End Function
Sub recursion(tp0 As Double, tp1 As Double, tq0 As Double, tq1 As Double, _
P As spower_curve, Q As spower_curve, tol As Double, spacing As Double, _
max_points As Integer, xs() As Double, ys() As Double, Byref num_points As Integer)
If num_points = max_points Then
' do nothing
Elseif Not flat_enough(spower_curve_portion(P, tp0, tp1), tol) Then
Dim As Double tp_half = (0.5 * tp0) + (0.5 * tp1)
If Not flat_enough(spower_curve_portion(Q, tq0, tq1), tol) Then
Dim As Double tq_half = (0.5 * tq0) + (0.5 * tq1)
recursion(tp0, tp_half, tq0, tq_half, P, Q, tol, _
spacing, max_points, xs(), ys(), num_points)
recursion(tp0, tp_half, tq_half, tq1, P, Q, tol, _
spacing, max_points, xs(), ys(), num_points)
recursion(tp_half, tp1, tq0, tq_half, P, Q, tol, _
spacing, max_points, xs(), ys(), num_points)
recursion(tp_half, tp1, tq_half, tq1, P, Q, tol, _
spacing, max_points, xs(), ys(), num_points)
Else
recursion(tp0, tp_half, tq0, tq1, P, Q, tol, _
spacing, max_points, xs(), ys(), num_points)
recursion(tp_half, tp1, tq0, tq1, P, Q, tol, _
spacing, max_points, xs(), ys(), num_points)
End If
Elseif Not flat_enough(spower_curve_portion(Q, tq0, tq1), tol) Then
Dim As Double tq_half = (0.5 * tq0) + (0.5 * tq1)
recursion(tp0, tp1, tq0, tq_half, P, Q, tol, _
spacing, max_points, xs(), ys(), num_points)
recursion(tp0, tp1, tq_half, tq1, P, Q, tol, _
spacing, max_points, xs(), ys(), num_points)
Else
Dim As spower_curve P1 = spower_curve_portion(P, tp0, tp1)
Dim As spower_curve Q1 = spower_curve_portion(Q, tq0, tq1)
Dim As Boolean they_intersect
Dim As Double x, y
test_line_segment_intersection(P1.x.c0, P1.x.c2, _
P1.y.c0, P1.y.c2, _
Q1.x.c0, Q1.x.c2, _
Q1.y.c0, Q1.y.c2, _
they_intersect, x, y)
If they_intersect And Not too_close(x, y, xs(), ys(), num_points, spacing) Then
xs(num_points) = x
ys(num_points) = y
num_points += 1
End If
End If
End Sub
Sub find_intersections(P As spower_curve, Q As spower_curve, _
flatness_tolerance As Double, point_spacing As Double, _
max_points As Integer, xs() As Double, ys() As Double, _
Byref num_points As Integer)
num_points = 0
recursion(0, 1, 0, 1, P, Q, flatness_tolerance, point_spacing, _
max_points, xs(), ys(), num_points)
End Sub
Dim As bernstein_spline bPx = Type<bernstein_spline>(-1, 0, 1)
Dim As bernstein_spline bPy = Type<bernstein_spline>(0, 10, 0)
Dim As bernstein_spline bQx = Type<bernstein_spline>(2, -8, 2)
Dim As bernstein_spline bQy = Type<bernstein_spline>(1, 2, 3)
Dim As spower_spline Px = bernstein_spline_to_spower(bPx)
Dim As spower_spline Py = bernstein_spline_to_spower(bPy)
Dim As spower_spline Qx = bernstein_spline_to_spower(bQx)
Dim As spower_spline Qy = bernstein_spline_to_spower(bQy)
Dim As spower_curve P = Type<spower_curve>(Px, Py)
Dim As spower_curve Q = Type<spower_curve>(Qx, Qy)
Dim As Double flatness_tolerance = 0.001
Dim As Double point_spacing = 0.000001 ' Max norm minimum spacing.
Const max_points As Integer = 10
Dim As Double xs(max_points)
Dim As Double ys(max_points)
Dim As Integer num_points
find_intersections(P, Q, flatness_tolerance, point_spacing, _
max_points, xs(), ys(), num_points)
For i As Integer = 0 To num_points - 1
Print "("; xs(i); ", "; ys(i); ")"
Next i
Sleep

Some files were not shown because too many files have changed in this diff Show more