Family Day update
This commit is contained in:
parent
aac6731f2c
commit
9ad63ea473
2442 changed files with 39761 additions and 8255 deletions
|
|
@ -3,29 +3,18 @@ namespace ConsoleApplication1
|
|||
using System;
|
||||
class Program
|
||||
{
|
||||
static void Main()
|
||||
static void Main(string[] args)
|
||||
{
|
||||
//The o variable stores the number of the next OPEN door.
|
||||
int o = 1;
|
||||
int f = 1;
|
||||
int l = 5;
|
||||
Random r = new Random();
|
||||
o = r.Next(f, l);
|
||||
//Perform the operation.
|
||||
bool[] doors = new bool[100];
|
||||
int n = 0;
|
||||
int d;
|
||||
while ((d = (++n * n)) <= 100)
|
||||
doors[d - 1] = true;
|
||||
|
||||
//The d variable determines the door to be output next.
|
||||
for (int d = 1; d <= 100; d++)
|
||||
{
|
||||
Console.Write("Door #{0}: ", d);
|
||||
if (d == o)
|
||||
{
|
||||
Console.WriteLine("Open");
|
||||
f = f + 5;
|
||||
l = l + 5;
|
||||
o = r.Next(f, l);
|
||||
}
|
||||
else
|
||||
Console.WriteLine("Closed");
|
||||
}
|
||||
//Perform the presentation.
|
||||
for (d = 0; d < doors.Length; d++)
|
||||
Console.WriteLine("Door #{0}: {1}", d + 1, doors[d] ? "Open" : "Closed");
|
||||
Console.ReadKey(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,17 +3,15 @@ namespace ConsoleApplication1
|
|||
using System;
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
static void Main()
|
||||
{
|
||||
//Perform the operation.
|
||||
bool[] doors = new bool[100];
|
||||
int n = 0;
|
||||
int d;
|
||||
while ((d = (++n * n)) <= 100)
|
||||
doors[d - 1] = true;
|
||||
|
||||
//Perform the presentation.
|
||||
for (d = 0; d < doors.Length; d++)
|
||||
//The number of passes can be 1-based, but the number of doors must be 0-based.
|
||||
for (int p = 1; p <= 100; p++)
|
||||
for (int d = p - 1; d < 100; d += p)
|
||||
doors[d] = !doors[d];
|
||||
for (int d = 0; d < 100; d++)
|
||||
Console.WriteLine("Door #{0}: {1}", d + 1, doors[d] ? "Open" : "Closed");
|
||||
Console.ReadKey(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,11 @@ namespace ConsoleApplication1
|
|||
{
|
||||
static void Main()
|
||||
{
|
||||
bool[] doors = new bool[100];
|
||||
double n;
|
||||
|
||||
//The number of passes can be 1-based, but the number of doors must be 0-based.
|
||||
for (int p = 1; p <= 100; p++)
|
||||
for (int d = p - 1; d < 100; d += p)
|
||||
doors[d] = !doors[d];
|
||||
for (int d = 0; d < 100; d++)
|
||||
Console.WriteLine("Door #{0}: {1}", d + 1, doors[d] ? "Open" : "Closed");
|
||||
//If the current door number is the perfect square of an integer, say it is open, else say it is closed.
|
||||
for (int d = 1; d <= 100; d++)
|
||||
Console.WriteLine("Door #{0}: {1}", d, (n = Math.Sqrt(d)) == (int)n ? "Open" : "Closed");
|
||||
Console.ReadKey(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
115
Task/100-doors/EDSAC-order-code/100-doors.edsac
Normal file
115
Task/100-doors/EDSAC-order-code/100-doors.edsac
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
[Hundred doors problem from Rosetta Code website]
|
||||
[EDSAC program, Initial Orders 2]
|
||||
|
||||
[Library subroutine M3. Prints header and is then overwritten.
|
||||
Here, the last character sets the teleprinter to figures.]
|
||||
PFGKIFAFRDLFUFOFE@A6FG@E8FEZPF
|
||||
@&*THE!OPEN!DOORS!ARE@&#
|
||||
..PZ [blank tape, needed to mark end of header text]
|
||||
|
||||
[Library subroutine P6. Prints strictly positive integer.
|
||||
32 locations; working locations 1, 4, 5]
|
||||
T56K [define load address for subroutine]
|
||||
GKA3FT25@H29@VFT4DA3@TFH30@S6@T1F
|
||||
V4DU4DAFG26@TFTFO5FA4DF4FS4F
|
||||
L4FT4DA1FS3@G9@EFSFO31@E20@J995FJF!F
|
||||
|
||||
T88K [define load address for main program]
|
||||
GK [set @ (theta) for relative addresses]
|
||||
|
||||
[The 100 doors are at locations 200..299.
|
||||
Doors are numbered 0..99 internally, and 1..100 for output.
|
||||
The base address and the number of doors can be varied.
|
||||
The value of a door is 0 if open, negative if closed.]
|
||||
|
||||
[Constants. Program also uses order 'P 1 F'
|
||||
which is permanently at absolute address 2.]
|
||||
[0] P200F [address of door #0]
|
||||
[1] P100F [number of doors, as an address]
|
||||
[2] UF [makes S order from T, since 'S' = 'T' + 'U']
|
||||
[3] MF [makes A order from T, since 'A' = 'T' + 'M']
|
||||
[4] V2047D [all 1's for "closed" (any negative value will do)]
|
||||
[5] &F [line feed]
|
||||
[6] @F [carriage return]
|
||||
[7] K4096F [teleprinter null[
|
||||
|
||||
[Variables]
|
||||
[8] PF [pass number; step when toggling doors]
|
||||
[9] PF [door number, as address, 0-based]
|
||||
[10] PF [order referring to door 0]
|
||||
|
||||
[Enter with acc = 0]
|
||||
[Part 1 : close all the doors]
|
||||
[11] T8@ [pass := 0 (used in part 2)]
|
||||
T9@ [door number := 0]
|
||||
A16@ [load 'T F' order]
|
||||
A@ [add base address]
|
||||
T10@ [store T order for door #0]
|
||||
[16] TF [clear acc; also serves as constant]
|
||||
A9@ [load door number]
|
||||
A10@ [make T order]
|
||||
T21@ [plant in code]
|
||||
A4@ [load value for "closed"]
|
||||
[21] TF [store in current door]
|
||||
A9@ [load door number]
|
||||
A2F [add 1]
|
||||
U9@ [update door number]
|
||||
S1@ [done all doors yet?]
|
||||
G16@ [if not, loop back]
|
||||
|
||||
[Part 2 : 100 passes, toggling the doors]
|
||||
[27] TF [clear acc]
|
||||
A8@ [load pass number]
|
||||
A2F [add 1]
|
||||
T8@ [save updated pass number]
|
||||
S2F [make -1]
|
||||
U9@ [door number := -1]
|
||||
A8@ [add pass number to get first door toggled on this pass]
|
||||
S1@ [gone beyond end?]
|
||||
E50@ [if so, move on to part 3]
|
||||
[36] A1@ [restore acc after test]
|
||||
U9@ [store current door number]
|
||||
A10@ [make T order to load status]
|
||||
U44@ [plant T order for first door in pass]
|
||||
A2@ [convert to S order]
|
||||
T43@ [plant S order]
|
||||
A4@ [load value for "closed"]
|
||||
[43] SF [subtract status; toggles status]
|
||||
[44] TF [update status]
|
||||
A9@ [load door number just toggled]
|
||||
A8@ [add pass number to get next door in pass]
|
||||
S1@ [gone beyond end?]
|
||||
G36@ [no, loop to do next door]
|
||||
E27@ [yes, loop to do next pass]
|
||||
|
||||
[Part 3 : Print list of open doors.
|
||||
Header has set teleprinter to figures.]
|
||||
[50] TF [clear acc]
|
||||
T9@ [door nr := 0]
|
||||
A10@ [T order for door 0]
|
||||
A3@ [convert to A order]
|
||||
T10@
|
||||
[55] TF
|
||||
A9@ [load door number]
|
||||
A10@ [make A order to load value]
|
||||
T59@ [plant in next order]
|
||||
[59] AF [acc := 0 if open, < 0 if closed]
|
||||
G69@ [skip if closed]
|
||||
A9@ [door number as address]
|
||||
A2F [add 1 for 1-based output]
|
||||
RD [shift 1 right, address --> integer]
|
||||
TF [store integer at 0 for printing]
|
||||
[65] A65@ [for return from subroutine]
|
||||
G56F [call subroutine to print door number]
|
||||
O6@ [followed by CRLF]
|
||||
O5@
|
||||
[69] TF [clear acc]
|
||||
A9@ [load door number]
|
||||
A2F [add 1]
|
||||
U9@ [update door number]
|
||||
S1@ [done all doors yet?]
|
||||
G55@ [if not, loop back]
|
||||
[75] O7@ [output null to flush teleprinter buffer]
|
||||
ZF [stop]
|
||||
E11Z [define relative start address]
|
||||
PF
|
||||
|
|
@ -1,6 +1,14 @@
|
|||
class HundredDoors {
|
||||
import java.util.BitSet;
|
||||
|
||||
public class HundredDoors {
|
||||
public static void main(String[] args) {
|
||||
for (int i = 1; i <= 10; i++)
|
||||
System.out.printf("Door %d is open.%n", i * i);
|
||||
final int n = 100;
|
||||
var a = new BitSet(n);
|
||||
for (int i = 1; i <= n; i++) {
|
||||
for (int j = i - 1; j < n; j += i) {
|
||||
a.flip(j);
|
||||
}
|
||||
}
|
||||
a.stream().map(i -> i + 1).forEachOrdered(System.out::println);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,6 @@
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
class HundredDoors {
|
||||
public static void main(String args[]) {
|
||||
String openDoors = IntStream.rangeClosed(1, 100)
|
||||
.filter(i -> Math.pow((int) Math.sqrt(i), 2) == i)
|
||||
.mapToObj(Integer::toString)
|
||||
.collect(Collectors.joining(", "));
|
||||
System.out.printf("Open doors: %s%n", openDoors);
|
||||
public static void main(String[] args) {
|
||||
for (int i = 1; i <= 10; i++)
|
||||
System.out.printf("Door %d is open.%n", i * i);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
Task/100-doors/Java/100-doors-4.java
Normal file
12
Task/100-doors/Java/100-doors-4.java
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
class HundredDoors {
|
||||
public static void main(String args[]) {
|
||||
String openDoors = IntStream.rangeClosed(1, 100)
|
||||
.filter(i -> Math.pow((int) Math.sqrt(i), 2) == i)
|
||||
.mapToObj(Integer::toString)
|
||||
.collect(Collectors.joining(", "));
|
||||
System.out.printf("Open doors: %s%n", openDoors);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,11 @@
|
|||
from strutils import format
|
||||
from strutils import `%`
|
||||
|
||||
proc check_doors() =
|
||||
const n = 100
|
||||
var is_open : array[1..n, bool] # auto-initialized to false
|
||||
# pass over the doors n times
|
||||
for pass in 1..n:
|
||||
var i = pass
|
||||
while i <= n:
|
||||
is_open[i] = not is_open[i]
|
||||
i += pass
|
||||
# print the result
|
||||
for door in 1..n:
|
||||
echo format("door $1 is $2.", door, (if is_open[door]: "open" else: "closed"))
|
||||
const numDoors = 100
|
||||
var doors: array[1..numDoors, bool]
|
||||
|
||||
check_doors()
|
||||
for pass in 1..numDoors:
|
||||
for door in countup(pass, numDoors, pass):
|
||||
doors[door] = not doors[door]
|
||||
|
||||
for door in 1..numDoors:
|
||||
echo "Door $1 is $2." % [$door, if doors[door]: "open" else: "closed"]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
var isOpen: array[1..100, bool]
|
||||
from strutils import `%`
|
||||
|
||||
for pass in countup(1, 100):
|
||||
for door in countup(pass,100,pass):
|
||||
isOpen[door] = not isOpen[door]
|
||||
const numDoors = 100
|
||||
var doors {.compileTime.}: array[1..numDoors, bool]
|
||||
|
||||
for i in countup(1, 100):
|
||||
if isOpen[i]:
|
||||
echo("Door ",i," is open.")
|
||||
proc calcDoors(): string =
|
||||
for pass in 1..numDoors:
|
||||
for door in countup(pass, numDoors, pass):
|
||||
doors[door] = not doors[door]
|
||||
for door in 1..numDoors:
|
||||
result.add("Door $1 is $2.\n" % [$door, if doors[door]: "open" else: "closed"])
|
||||
|
||||
const outputString: string = calcDoors()
|
||||
|
||||
echo outputString
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
: doors
|
||||
| i j l |
|
||||
100 #[ false ] Array init dup ->l
|
||||
100 false Array newWith dup ->l
|
||||
100 loop: i [
|
||||
i 100 i step: j [ l put(j, l at(j) not) ]
|
||||
i 100 i step: j [ l put ( j , j l at not ) ]
|
||||
]
|
||||
l . ;
|
||||
;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
say "Door $_ is open" for 1..10 X** 2;
|
||||
say 'Door $_ is open' for (1..10)»²;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
say "Door $_ is ", <closed open>[.sqrt == .sqrt.floor] for 1..100;
|
||||
say "Door $_ is open" for 1..10 X** 2;
|
||||
|
|
|
|||
|
|
@ -1,26 +1 @@
|
|||
sub output( @arr, $max ) {
|
||||
my $output = 1;
|
||||
for 1..^$max -> $index {
|
||||
if @arr[$index] {
|
||||
printf "%4d", $index;
|
||||
say '' if $output++ %% 10;
|
||||
}
|
||||
}
|
||||
say '';
|
||||
}
|
||||
|
||||
sub MAIN ( Int :$doors = 100 ) {
|
||||
my $doorcount = $doors + 1;
|
||||
my @door[$doorcount] = 0 xx ($doorcount);
|
||||
|
||||
INDEX:
|
||||
for 1...^$doorcount -> $index {
|
||||
# flip door $index & its multiples, up to last door.
|
||||
#
|
||||
for ($index, * + $index ... *)[^$doors] -> $multiple {
|
||||
next INDEX if $multiple > $doors;
|
||||
@door[$multiple] = @door[$multiple] ?? 0 !! 1;
|
||||
}
|
||||
}
|
||||
output @door, $doors+1;
|
||||
}
|
||||
say "Door $_ is ", <closed open>[.sqrt == .sqrt.floor] for 1..100;
|
||||
|
|
|
|||
26
Task/100-doors/Perl-6/100-doors-6.pl6
Normal file
26
Task/100-doors/Perl-6/100-doors-6.pl6
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
sub output( @arr, $max ) {
|
||||
my $output = 1;
|
||||
for 1..^$max -> $index {
|
||||
if @arr[$index] {
|
||||
printf "%4d", $index;
|
||||
say '' if $output++ %% 10;
|
||||
}
|
||||
}
|
||||
say '';
|
||||
}
|
||||
|
||||
sub MAIN ( Int :$doors = 100 ) {
|
||||
my $doorcount = $doors + 1;
|
||||
my @door[$doorcount] = 0 xx ($doorcount);
|
||||
|
||||
INDEX:
|
||||
for 1...^$doorcount -> $index {
|
||||
# flip door $index & its multiples, up to last door.
|
||||
#
|
||||
for ($index, * + $index ... *)[^$doors] -> $multiple {
|
||||
next INDEX if $multiple > $doors;
|
||||
@door[$multiple] = @door[$multiple] ?? 0 !! 1;
|
||||
}
|
||||
}
|
||||
output @door, $doors+1;
|
||||
}
|
||||
|
|
@ -1,3 +1,2 @@
|
|||
: squared ( n-n ) dup * ;
|
||||
: doors ( n- ) [ 1 repeat 2over squared > 0; drop dup squared putn space 1+ again ] do 2drop ;
|
||||
100 doors
|
||||
:doors (n-) [ #1 repeat dup-pair n:square gt? 0; drop dup n:square n:put sp n:inc again ] do drop-pair ;
|
||||
#100 doors
|
||||
|
|
|
|||
30
Task/100-doors/V/100-doors.v
Normal file
30
Task/100-doors/V/100-doors.v
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
fn main() {
|
||||
mut is_open := [false].repeat(100)
|
||||
|
||||
// do 100 passes
|
||||
for pass := 0; pass < 100; pass++ {
|
||||
for door := pass; door < 100; door += pass + 1 {
|
||||
// there is no NOT operator in V.
|
||||
is_open[door] = match is_open[door] {
|
||||
true { false }
|
||||
false { true }
|
||||
else { false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// output results
|
||||
for door := 0; door < 100; door ++ {
|
||||
print( "door #" )
|
||||
print( door + 1 )
|
||||
print(
|
||||
if is_open[door] {
|
||||
" is open."
|
||||
}
|
||||
else {
|
||||
" is closed."
|
||||
}
|
||||
)
|
||||
println("")
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@ import system'collections;
|
|||
import system'dynamic;
|
||||
import extensions;
|
||||
|
||||
// --- Expression ---
|
||||
|
||||
class ExpressionTree
|
||||
{
|
||||
object theTree;
|
||||
|
|
@ -68,7 +70,7 @@ class ExpressionTree
|
|||
|
||||
var op := node.Operation;
|
||||
|
||||
^ mixin op(left).eval:right
|
||||
^ op(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,8 +82,6 @@ class ExpressionTree
|
|||
if (nil == node)
|
||||
{ InvalidArgumentException.raise() };
|
||||
|
||||
var s := subjconst Leaf;
|
||||
|
||||
if (node.containsProperty(subjconst Leaf))
|
||||
{
|
||||
list.append(node.Leaf)
|
||||
|
|
@ -97,6 +97,8 @@ class ExpressionTree
|
|||
<= readLeaves(list,theTree);
|
||||
}
|
||||
|
||||
// --- Game ---
|
||||
|
||||
class TwentyFourGame
|
||||
{
|
||||
object theNumbers;
|
||||
|
|
@ -109,12 +111,12 @@ class TwentyFourGame
|
|||
newPuzzle()
|
||||
{
|
||||
theNumbers := new object[]
|
||||
{
|
||||
1 + randomGenerator.eval:9,
|
||||
1 + randomGenerator.eval:9,
|
||||
1 + randomGenerator.eval:9,
|
||||
1 + randomGenerator.eval:9
|
||||
}
|
||||
{
|
||||
1 + randomGenerator.eval:9,
|
||||
1 + randomGenerator.eval:9,
|
||||
1 + randomGenerator.eval:9,
|
||||
1 + randomGenerator.eval:9
|
||||
}
|
||||
}
|
||||
|
||||
help()
|
||||
|
|
|
|||
101
Task/24-game/Objeck/24-game.objeck
Normal file
101
Task/24-game/Objeck/24-game.objeck
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
use Collection.Generic;
|
||||
use System.Matrix;
|
||||
|
||||
class RPNParser {
|
||||
@stk : Stack<IntHolder>;
|
||||
@digits : List<IntHolder>;
|
||||
|
||||
function : Main(args : String[]) ~ Nil {
|
||||
digits := List->New()<IntHolder>;
|
||||
"Make 24 with the digits: "->Print();
|
||||
for(i := 0; i < 4; i += 1;) {
|
||||
n : Int := Int->Random(1, 9);
|
||||
" {$n}"->Print();
|
||||
digits->AddBack(n);
|
||||
};
|
||||
'\n'->Print();
|
||||
|
||||
parser := RPNParser->New();
|
||||
if(parser->Parse(System.IO.Console->ReadString(), digits)) {
|
||||
result := parser->GetResult();
|
||||
if(result = 24) {
|
||||
"Good job!"->PrintLine();
|
||||
}
|
||||
else {
|
||||
"{$result}, Try again."->PrintLine();
|
||||
};
|
||||
}
|
||||
else {
|
||||
"Invalid sequence"->PrintLine();
|
||||
};
|
||||
}
|
||||
|
||||
New() {
|
||||
@stk := Stack->New()<IntHolder>;
|
||||
@digits := List->New()<IntHolder>;
|
||||
}
|
||||
|
||||
method : Op(f : \Func->Calc) ~ Nil {
|
||||
if(@stk->Size() < 2) { "Improperly written expression"->ErrorLine(); Runtime->Exit(1); };
|
||||
b := @stk->Pop();
|
||||
a := @stk->Pop();
|
||||
@stk->Push(f(a, b));
|
||||
}
|
||||
|
||||
method : Parse(c : Char) ~ Nil {
|
||||
if(c >= '0' & c <= '9') {
|
||||
value : Int := c - '0';
|
||||
@stk->Push(value);
|
||||
@digits->AddBack(value);
|
||||
}
|
||||
else if(c = '+') {
|
||||
Op(\Func->Calc : (a, b) => a + b);
|
||||
}
|
||||
else if(c = '-') {
|
||||
Op(\Func->Calc : (a, b) => a - b);
|
||||
}
|
||||
else if(c = '*') {
|
||||
Op(\Func->Calc : (a, b) => a * b);
|
||||
}
|
||||
else if(c = '/') {
|
||||
Op(\Func->Calc : (a, b) => { if(b <> 0) { return a / b; } else { return 0; }; });
|
||||
};
|
||||
}
|
||||
|
||||
method : GetResult() ~ Int {
|
||||
if(@stk->Size() = 1) {
|
||||
return @stk->Top();
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
method : Parse(s : String, digits : List<IntHolder>) ~ Bool {
|
||||
each(i : s) {
|
||||
Parse(s->Get(i));
|
||||
};
|
||||
|
||||
@digits->Rewind();
|
||||
while(@digits->More()) {
|
||||
left := @digits->Get()->Get();
|
||||
digits->Rewind();
|
||||
found := false;
|
||||
while(digits->More() & found = false) {
|
||||
right := digits->Get()->Get();
|
||||
if(left = right) {
|
||||
digits->Remove(); found := true;
|
||||
}
|
||||
else {
|
||||
digits->Next();
|
||||
};
|
||||
};
|
||||
@digits->Next();
|
||||
};
|
||||
|
||||
return digits->IsEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
alias Func {
|
||||
Calc : (IntHolder, IntHolder) ~ IntHolder
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
import 'dart:math';
|
||||
|
||||
List<BigInt> partitions(int n) {
|
||||
var cache = List<List<BigInt>>.filled(1, List<BigInt>.filled(1, BigInt.from(1)), growable: true);
|
||||
for(int length = cache.length; length < n + 1; length++) {
|
||||
var row = List<BigInt>.filled(1, BigInt.from(0), growable: true);
|
||||
for(int index = 1; index < length + 1; index++) {
|
||||
var partAtIndex = row[row.length - 1] + cache[length - index][min(index, length - index)];
|
||||
row.add(partAtIndex);
|
||||
}
|
||||
cache.add(row);
|
||||
}
|
||||
return cache[n];
|
||||
}
|
||||
|
||||
List<BigInt> row(int n) {
|
||||
var parts = partitions(n);
|
||||
return List<BigInt>.generate(n, (int index) => parts[index + 1] - parts[index]);
|
||||
}
|
||||
|
||||
void printRows({int min = 1, int max = 11}) {
|
||||
int maxDigits = max.toString().length;
|
||||
print('Rows:');
|
||||
for(int i in List.generate(max - min, (int index) => index + min)) {
|
||||
print((' ' * (maxDigits - i.toString().length)) + '$i: ${row(i)}');
|
||||
}
|
||||
}
|
||||
|
||||
void printSums(List<int> args) {
|
||||
print('Sums:');
|
||||
for(int i in args) {
|
||||
print('$i: ${partitions(i)[i]}');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import 'package:DD1_NamesOfGod/DD1_NamesOfGod.dart' as names_of_god;
|
||||
|
||||
main(List<String> arguments) {
|
||||
names_of_god.printRows(min: 1, max: 11);
|
||||
names_of_god.printSums([23, 123, 1234, 12345]);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
USING: combinators io kernel math math.ranges memoize prettyprint
|
||||
sequences ;
|
||||
|
||||
MEMO: p ( m n -- o )
|
||||
{
|
||||
{ [ dup zero? ] [ nip ] }
|
||||
{ [ 2dup = ] [ 2drop 1 ] }
|
||||
{ [ 2dup < ] [ 2drop 0 ] }
|
||||
[ [ [ 1 - ] bi@ p ] [ [ - ] [ ] bi p + ] 2bi ]
|
||||
} cond ;
|
||||
|
||||
: row ( n -- seq ) dup [1,b] [ p ] with map ;
|
||||
|
||||
: .row ( n -- ) row [ pprint bl ] each nl ;
|
||||
|
||||
: .triangle ( n -- ) [1,b] [ .row ] each ;
|
||||
|
||||
: G ( n -- sum ) row sum ;
|
||||
|
||||
25 .triangle nl
|
||||
"Sums:" print { 23 123 1234 12345 } [ dup pprint bl G . ] each
|
||||
|
|
@ -6,11 +6,11 @@ import extensions'text;
|
|||
extension bottleOp
|
||||
{
|
||||
bottleDescription()
|
||||
= self.Printable + (self != 1).iif(" bottles"," bottle");
|
||||
= self.toPrintable() + (self != 1).iif(" bottles"," bottle");
|
||||
|
||||
bottleEnumerator() = new Variable(self).doWith:(n)
|
||||
{
|
||||
^ new Enumerator:
|
||||
^ new Enumerator
|
||||
{
|
||||
bool next() = n > 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
-- An alternate version
|
||||
|
||||
include std/console.e
|
||||
|
||||
sequence howmany = {"No more bottles","%d bottle","","s"}
|
||||
|
||||
for beer = 99 to 1 by -1 do
|
||||
display(`
|
||||
[1] bottles of beer on the wall,
|
||||
[1] bottles of beer.
|
||||
Take one down, drink it right down,
|
||||
[2][3] of beer.
|
||||
`,{beer,
|
||||
sprintf(howmany[(beer>1)+1],beer-1),
|
||||
howmany[(beer>2)+3]
|
||||
})
|
||||
end for
|
||||
|
|
@ -19,12 +19,12 @@ end function
|
|||
|
||||
string this = bob(ninetynine)
|
||||
string that = "Take one down, pass it around,\n"
|
||||
for i=ninetynine to 0 by -1 do
|
||||
puts(1,up1(this)&" on the wall,\n")
|
||||
puts(1,this&".\n")
|
||||
if i=0 then that = "Go to the store, buy some more,\n"
|
||||
elsif i=1 then that[6..8] = "it" end if
|
||||
this = bob(i-1)
|
||||
puts(1,that&this&" on the wall.\n\n")
|
||||
end for
|
||||
if getc(0) then end if
|
||||
for i=ninetynine to 0 by -1 do
|
||||
puts(1,up1(this)&" on the wall,\n")
|
||||
puts(1,this&".\n")
|
||||
if i=0 then that = "Go to the store, buy some more,\n"
|
||||
elsif i=1 then that[6..8] = "it" end if
|
||||
this = bob(i-1)
|
||||
puts(1,that&this&" on the wall.\n\n")
|
||||
end for
|
||||
{} = wait_key()
|
||||
|
|
|
|||
20
Task/99-Bottles-of-Beer/Pony/99-bottles-of-beer-1.pony
Normal file
20
Task/99-Bottles-of-Beer/Pony/99-bottles-of-beer-1.pony
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
actor Main
|
||||
let _env: Env
|
||||
new create(env: Env) =>
|
||||
_env = env
|
||||
bottles(99)
|
||||
|
||||
be bottles(n: U32) =>
|
||||
if n == 0 then
|
||||
_env.out.print("No more bottles of beer on the wall, no more bottles of beer.")
|
||||
_env.out.print("Go to the store and buy some more, 99 bottles of beer on the wall.")
|
||||
else
|
||||
if n == 1 then
|
||||
_env.out.print("1 bottle of beer on the wall, 1 bottle of beer.")
|
||||
_env.out.print("Take one down and pass it around, no more bottles of beer on the wall.\n")
|
||||
else
|
||||
_env.out.print(n.string() + " bottles of beer on the wall, " + n.string() + " bottles of beer.")
|
||||
_env.out.print("Take one down and pass it around, "+ (n - 1).string() +" bottles of beer on the wall.\n")
|
||||
end
|
||||
bottles(n-1)
|
||||
end
|
||||
18
Task/99-Bottles-of-Beer/Pony/99-bottles-of-beer-2.pony
Normal file
18
Task/99-Bottles-of-Beer/Pony/99-bottles-of-beer-2.pony
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
actor Main
|
||||
let _env: Env
|
||||
new create(env: Env) =>
|
||||
_env = env
|
||||
var n: I32 = 99
|
||||
repeat
|
||||
if n == 0 then
|
||||
_env.out.print("No more bottles of beer on the wall, no more bottles of beer.")
|
||||
_env.out.print("Go to the store and buy some more, 99 bottles of beer on the wall.")
|
||||
elseif n == 1 then
|
||||
_env.out.print("1 bottle of beer on the wall, 1 bottle of beer.")
|
||||
_env.out.print("Take one down and pass it around, no more bottles of beer on the wall.\n")
|
||||
else
|
||||
_env.out.print(n.string() + " bottles of beer on the wall, " + n.string() + " bottles of beer.")
|
||||
_env.out.print("Take one down and pass it around, "+ (n - 1).string() +" bottles of beer on the wall.\n")
|
||||
end
|
||||
n = n - 1
|
||||
until n < 0 end
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
for (int i = 99; i > 0; i--) {
|
||||
print(i + " bottles of beer on the wall\n" + i + " bottles of beer\nTake one down, pass it around\n" + (i - 1) + " bottles of beer on the wall\n\n");
|
||||
}
|
||||
5
Task/99-Bottles-of-Beer/Processing/99-bottles-of-beer-1
Normal file
5
Task/99-Bottles-of-Beer/Processing/99-bottles-of-beer-1
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
for (int i = 99; i > 0; i--) {
|
||||
print(i + " bottles of beer on the wall\n"
|
||||
+ i + " bottles of beer\nTake one down, pass it around\n"
|
||||
+ (i - 1) + " bottles of beer on the wall\n\n");
|
||||
}
|
||||
18
Task/99-Bottles-of-Beer/Processing/99-bottles-of-beer-2
Normal file
18
Task/99-Bottles-of-Beer/Processing/99-bottles-of-beer-2
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
int i = 99;
|
||||
void setup() {
|
||||
size(200, 140);
|
||||
}
|
||||
void draw() {
|
||||
background(0);
|
||||
text(i + " bottles of beer on the wall\n"
|
||||
+ i + " bottles of beer\nTake one down, pass it around\n"
|
||||
+ (i - 1) + " bottles of beer on the wall\n\n",
|
||||
10, 20);
|
||||
if (frameCount%240==239) next(); // auto-advance every 4 secs
|
||||
}
|
||||
void mouseReleased() {
|
||||
next(); // manual advance
|
||||
}
|
||||
void next() {
|
||||
i = max(i-1, 1); // stop decreasing at 1-0 bottles
|
||||
}
|
||||
|
|
@ -1,28 +1,10 @@
|
|||
"""Pythonic 99 beer song (readability counts)."""
|
||||
catchphrase = "%d bottles of beer on the wall"
|
||||
|
||||
regular_verse = '''\
|
||||
{n} bottles of beer on the wall, {n} bottles of beer
|
||||
Take one down and pass it around, {n_minus_1} bottles of beer on the wall.
|
||||
strofas = ("\n".join((
|
||||
catchphrase % n,
|
||||
catchphrase[:18] % n,
|
||||
"Take one down and pass it around",
|
||||
catchphrase % (n-1)
|
||||
)) for n in range(99, 0, -1))
|
||||
|
||||
'''
|
||||
|
||||
ending_verses = '''\
|
||||
2 bottles of beer on the wall, 2 bottles of beer.
|
||||
Take one down and pass it around, 1 bottle of beer on the wall.
|
||||
|
||||
1 bottle of beer on the wall, 1 bottle of beer.
|
||||
Take one down and pass it around, no more bottles of beer on the wall.
|
||||
|
||||
No more bottles of beer on the wall, no more bottles of beer.
|
||||
Go to the store and buy some more, 99 bottles of beer on the wall.
|
||||
|
||||
'''
|
||||
|
||||
# @todo: It is possible to refactor the code to avoid n-1 in the code,
|
||||
# notice that the last line of any verse and the first line of the next
|
||||
# verse share the same number of bottles. Nevertheless the code
|
||||
# would be less readliable.
|
||||
|
||||
for n in range(99, 2, -1):
|
||||
print(regular_verse.format(n=n, n_minus_1=n - 1))
|
||||
print(ending_verses)
|
||||
print("\n\n".join(strofas))
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
"""Pythonic 99 beer song (readability counts)."""
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
first = '''\
|
||||
99 bottles of beer on the wall, 99 bottles of beer
|
||||
'''
|
||||
"""Pythonic 99 beer song (maybe the simplest naive implementation in Python 3)."""
|
||||
|
||||
middle = '''\
|
||||
Take one down and pass it around, {n} bottles of beer on the wall.
|
||||
|
||||
REGULAR_VERSE = '''\
|
||||
{n} bottles of beer on the wall, {n} bottles of beer
|
||||
Take one down and pass it around, {n_minus_1} bottles of beer on the wall.
|
||||
|
||||
'''
|
||||
|
||||
last = '''\
|
||||
ENDING_VERSES = '''\
|
||||
2 bottles of beer on the wall, 2 bottles of beer.
|
||||
Take one down and pass it around, 1 bottle of beer on the wall.
|
||||
|
||||
1 bottle of beer on the wall, 1 bottle of beer.
|
||||
|
|
@ -18,9 +19,10 @@ Take one down and pass it around, no more bottles of beer on the wall.
|
|||
|
||||
No more bottles of beer on the wall, no more bottles of beer.
|
||||
Go to the store and buy some more, 99 bottles of beer on the wall.
|
||||
|
||||
'''
|
||||
|
||||
print(first)
|
||||
for n in range(98, 1, -1):
|
||||
print(middle.format(n=n))
|
||||
print(last)
|
||||
|
||||
for n in range(99, 2, -1):
|
||||
print(REGULAR_VERSE.format(n=n, n_minus_1=n - 1))
|
||||
print(ENDING_VERSES)
|
||||
|
|
|
|||
|
|
@ -1,23 +1,34 @@
|
|||
"""99 Bottles of Beer on the Wall made functional"""
|
||||
"""
|
||||
99 Bottles of Beer on the Wall made functional
|
||||
|
||||
Main function accepts a number of parameters, so you can specify a name of
|
||||
the drink, its container and other things. English only.
|
||||
"""
|
||||
|
||||
from functools import partial
|
||||
from typing import Callable
|
||||
|
||||
|
||||
def regular_plural(noun: str) -> str:
|
||||
"""Regular rule to get the plural form of a word"""
|
||||
"""English rule to get the plural form of a word"""
|
||||
if noun[-1] == "s":
|
||||
return noun + "es"
|
||||
|
||||
return noun + "s"
|
||||
|
||||
|
||||
def beer_song(*,
|
||||
location: str = 'on the wall',
|
||||
distribution: str = 'Take one down, pass it around',
|
||||
solution: str = 'Better go to the store to buy some more!',
|
||||
container: str = 'bottle',
|
||||
plurifier: Callable[[str], str] = regular_plural,
|
||||
liquid: str = "beer",
|
||||
initial_count: int = 99) -> None:
|
||||
def beer_song(
|
||||
*,
|
||||
location: str = 'on the wall',
|
||||
distribution: str = 'Take one down, pass it around',
|
||||
solution: str = 'Better go to the store to buy some more!',
|
||||
container: str = 'bottle',
|
||||
plurifier: Callable[[str], str] = regular_plural,
|
||||
liquid: str = "beer",
|
||||
initial_count: int = 99,
|
||||
) -> str:
|
||||
"""
|
||||
Displays the lyrics of the beer song
|
||||
Return the lyrics of the beer song
|
||||
:param location: initial location of the drink
|
||||
:param distribution: specifies the process of its distribution
|
||||
:param solution: what happens when we run out of drinks
|
||||
|
|
@ -26,68 +37,92 @@ def beer_song(*,
|
|||
:param liquid: the name of the drink in the given container
|
||||
:param initial_count: how many containers available initially
|
||||
"""
|
||||
verse = partial(get_verse,
|
||||
location=location,
|
||||
distribution=distribution,
|
||||
solution=solution,
|
||||
container=container,
|
||||
plurifier=plurifier,
|
||||
liquid=liquid)
|
||||
|
||||
verse = partial(
|
||||
get_verse,
|
||||
initial_count = initial_count,
|
||||
location = location,
|
||||
distribution = distribution,
|
||||
solution = solution,
|
||||
container = container,
|
||||
plurifier = plurifier,
|
||||
liquid = liquid,
|
||||
)
|
||||
|
||||
verses = map(verse, range(initial_count, -1, -1))
|
||||
print(*verses, sep='\n\n')
|
||||
return '\n\n'.join(verses)
|
||||
|
||||
|
||||
def get_verse(count: int,
|
||||
*,
|
||||
location: str,
|
||||
distribution: str,
|
||||
solution: str,
|
||||
container: str,
|
||||
plurifier: Callable[[str], str],
|
||||
liquid: str) -> str:
|
||||
"""Returns the verse for the given initial amount of drinks"""
|
||||
inventory = partial(get_inventory,
|
||||
location=location)
|
||||
asset = partial(get_asset,
|
||||
container=container,
|
||||
plurifier=plurifier,
|
||||
liquid=liquid)
|
||||
initial_asset = asset(count)
|
||||
final_asset = asset(count - 1)
|
||||
standard_verse = '\n'.join([inventory(initial_asset),
|
||||
initial_asset,
|
||||
distribution,
|
||||
inventory(final_asset)])
|
||||
return solution if count == 0 else standard_verse
|
||||
def get_verse(
|
||||
count: int,
|
||||
*,
|
||||
initial_count: str,
|
||||
location: str,
|
||||
distribution: str,
|
||||
solution: str,
|
||||
container: str,
|
||||
plurifier: Callable[[str], str],
|
||||
liquid: str,
|
||||
) -> str:
|
||||
"""Returns the verse for the given amount of drinks"""
|
||||
|
||||
asset = partial(
|
||||
get_asset,
|
||||
container = container,
|
||||
plurifier = plurifier,
|
||||
liquid = liquid,
|
||||
)
|
||||
|
||||
current_asset = asset(count)
|
||||
next_number = count - 1 if count else initial_count
|
||||
next_asset = asset(next_number)
|
||||
action = distribution if count else solution
|
||||
|
||||
inventory = partial(
|
||||
get_inventory,
|
||||
location = location,
|
||||
)
|
||||
|
||||
return '\n'.join((
|
||||
inventory(current_asset),
|
||||
current_asset,
|
||||
action,
|
||||
inventory(next_asset),
|
||||
))
|
||||
|
||||
|
||||
def get_inventory(asset: str,
|
||||
*,
|
||||
location: str) -> str:
|
||||
def get_inventory(
|
||||
asset: str,
|
||||
*,
|
||||
location: str,
|
||||
) -> str:
|
||||
"""
|
||||
Used to return the first or the fourth line of the verse
|
||||
|
||||
>>> get_inventory("10 bottles of beer", location="on the wall")
|
||||
"10 bottles of beer on the wall"
|
||||
"""
|
||||
return ' '.join([asset, location])
|
||||
return ' '.join((asset, location))
|
||||
|
||||
|
||||
def get_asset(count: int,
|
||||
*,
|
||||
container: str,
|
||||
plurifier: Callable[[str], str],
|
||||
liquid: str) -> str:
|
||||
def get_asset(
|
||||
count: int,
|
||||
*,
|
||||
container: str,
|
||||
plurifier: Callable[[str], str],
|
||||
liquid: str,
|
||||
) -> str:
|
||||
"""
|
||||
Quantified asset
|
||||
|
||||
>>> get_asset(0, container="jar", plurifier=regular_plural, liquid='milk')
|
||||
"No more jars of milk"
|
||||
"""
|
||||
containers = container if count == 1 else plurifier(container)
|
||||
spelled_out_quantity = "No more" if count == 0 else str(count)
|
||||
return ' '.join([spelled_out_quantity, containers, "of", liquid])
|
||||
|
||||
containers = plurifier(container) if count != 1 else container
|
||||
spelled_out_quantity = str(count) if count else "No more"
|
||||
return ' '.join((spelled_out_quantity, containers, "of", liquid))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
beer_song()
|
||||
print(beer_song())
|
||||
|
|
|
|||
256
Task/99-Bottles-of-Beer/Python/99-bottles-of-beer-5.py
Normal file
256
Task/99-Bottles-of-Beer/Python/99-bottles-of-beer-5.py
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
"""
|
||||
Excercise of style. An overkill for the task :-D
|
||||
|
||||
1. OOP, with abstract class and implementation with much common magic methods
|
||||
2. you can customize:
|
||||
a. the initial number
|
||||
b. the name of the item and its plural
|
||||
c. the string to display when there's no more items
|
||||
d. the normal action
|
||||
e. the final action
|
||||
f. the template used, for foreign languages
|
||||
3. strofas of the song are created with multiprocessing
|
||||
4. when you launch it as a script, you can specify an optional parameter for
|
||||
the number of initial items
|
||||
"""
|
||||
|
||||
from string import Template
|
||||
from abc import ABC, abstractmethod
|
||||
from multiprocessing.pool import Pool as ProcPool
|
||||
from functools import partial
|
||||
import sys
|
||||
|
||||
class Song(ABC):
|
||||
@abstractmethod
|
||||
def sing(self):
|
||||
"""
|
||||
it must return the song as a text-like object
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
class MuchItemsSomewhere(Song):
|
||||
eq_attrs = (
|
||||
"initial_number",
|
||||
"zero_items",
|
||||
"action1",
|
||||
"action2",
|
||||
"item",
|
||||
"items",
|
||||
"strofa_tpl"
|
||||
)
|
||||
|
||||
hash_attrs = eq_attrs
|
||||
repr_attrs = eq_attrs
|
||||
|
||||
__slots__ = eq_attrs + ("_repr", "_hash")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
items = "bottles of beer",
|
||||
item = "bottle of beer",
|
||||
where = "on the wall",
|
||||
initial_number = None,
|
||||
zero_items = "No more",
|
||||
action1 = "Take one down, pass it around",
|
||||
action2 = "Go to the store, buy some more",
|
||||
template = None,
|
||||
):
|
||||
initial_number_true = 99 if initial_number is None else initial_number
|
||||
|
||||
try:
|
||||
is_initial_number_int = (initial_number_true % 1) == 0
|
||||
except Exception:
|
||||
is_initial_number_int = False
|
||||
|
||||
if not is_initial_number_int:
|
||||
raise ValueError("`initial_number` parameter must be None or a int-like object")
|
||||
|
||||
if initial_number_true < 0:
|
||||
raise ValueError("`initial_number` parameter must be >=0")
|
||||
|
||||
|
||||
true_tpl = template or """\
|
||||
$i $items1 $where
|
||||
$i $items1
|
||||
$action
|
||||
$j $items2 $where"""
|
||||
|
||||
strofa_tpl_tmp = Template(true_tpl)
|
||||
strofa_tpl = Template(strofa_tpl_tmp.safe_substitute(where=where))
|
||||
|
||||
self.zero_items = zero_items
|
||||
self.action1 = action1
|
||||
self.action2 = action2
|
||||
self.initial_number = initial_number_true
|
||||
self.item = item
|
||||
self.items = items
|
||||
self.strofa_tpl = strofa_tpl
|
||||
self._hash = None
|
||||
self._repr = None
|
||||
|
||||
def strofa(self, number):
|
||||
zero_items = self.zero_items
|
||||
item = self.item
|
||||
items = self.items
|
||||
|
||||
if number == 0:
|
||||
i = zero_items
|
||||
action = self.action2
|
||||
j = self.initial_number
|
||||
else:
|
||||
i = number
|
||||
action = self.action1
|
||||
j = i - 1
|
||||
|
||||
if i == 1:
|
||||
items1 = item
|
||||
j = zero_items
|
||||
else:
|
||||
items1 = items
|
||||
|
||||
if j == 1:
|
||||
items2 = item
|
||||
else:
|
||||
items2 = items
|
||||
|
||||
return self.strofa_tpl.substitute(
|
||||
i = i,
|
||||
j = j,
|
||||
action = action,
|
||||
items1 = items1,
|
||||
items2 = items2
|
||||
)
|
||||
|
||||
def sing(self):
|
||||
with ProcPool() as proc_pool:
|
||||
strofa = self.strofa
|
||||
initial_number = self.initial_number
|
||||
args = range(initial_number, -1, -1)
|
||||
return "\n\n".join(proc_pool.map(strofa, args))
|
||||
|
||||
def __copy__(self, *args, **kwargs):
|
||||
return self
|
||||
|
||||
def __deepcopy__(self, *args, **kwargs):
|
||||
return self
|
||||
|
||||
def __eq__(self, other, *args, **kwargs):
|
||||
if self is other:
|
||||
return True
|
||||
|
||||
getmyattr = partial(getattr, self)
|
||||
getotherattr = partial(getattr, other)
|
||||
eq_attrs = self.eq_attrs
|
||||
|
||||
for attr in eq_attrs:
|
||||
val = getmyattr(attr)
|
||||
|
||||
try:
|
||||
val2 = getotherattr(attr)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
if attr == "strofa_tpl":
|
||||
val_true = val.safe_substitute()
|
||||
val2_true = val.safe_substitute()
|
||||
else:
|
||||
val_true = val
|
||||
val2_true = val
|
||||
|
||||
if val_true != val2_true:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def __hash__(self, *args, **kwargs):
|
||||
_hash = self._hash
|
||||
|
||||
if _hash is None:
|
||||
getmyattr = partial(getattr, self)
|
||||
attrs = self.hash_attrs
|
||||
hash_true = self._hash = hash(tuple(map(getmyattr, attrs)))
|
||||
else:
|
||||
hash_true = _hash
|
||||
|
||||
return hash_true
|
||||
|
||||
def __repr__(self, *args, **kwargs):
|
||||
_repr = self._repr
|
||||
|
||||
if _repr is None:
|
||||
repr_attrs = self.repr_attrs
|
||||
getmyattr = partial(getattr, self)
|
||||
|
||||
attrs = []
|
||||
|
||||
for attr in repr_attrs:
|
||||
val = getmyattr(attr)
|
||||
|
||||
if attr == "strofa_tpl":
|
||||
val_true = val.safe_substitute()
|
||||
else:
|
||||
val_true = val
|
||||
|
||||
attrs.append(f"{attr}={repr(val_true)}")
|
||||
|
||||
repr_true = self._repr = f"{self.__class__.__name__}({', '.join(attrs)})"
|
||||
else:
|
||||
repr_true = _repr
|
||||
|
||||
return repr_true
|
||||
|
||||
def muchBeersOnTheWall(num):
|
||||
song = MuchItemsSomewhere(initial_number=num)
|
||||
|
||||
return song.sing()
|
||||
|
||||
def balladOfProgrammer(num):
|
||||
"""
|
||||
Prints
|
||||
"99 Subtle Bugs in Production"
|
||||
or
|
||||
"The Ballad of Programmer"
|
||||
"""
|
||||
|
||||
song = MuchItemsSomewhere(
|
||||
initial_number = num,
|
||||
items = "subtle bugs",
|
||||
item = "subtle bug",
|
||||
where = "in Production",
|
||||
action1 = "Debug and catch, commit a patch",
|
||||
action2 = "Release the fixes, wait for some tickets",
|
||||
zero_items = "Zarro",
|
||||
)
|
||||
|
||||
return song.sing()
|
||||
|
||||
def main(num):
|
||||
print(f"### {num} Bottles of Beers on the Wall ###")
|
||||
print()
|
||||
print(muchBeersOnTheWall(num))
|
||||
print()
|
||||
print()
|
||||
print('### "The Ballad of Programmer", by Marco Sulla')
|
||||
print()
|
||||
print(balladOfProgrammer(num))
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Ok, argparse is **really** too much
|
||||
argv = sys.argv
|
||||
|
||||
if len(argv) == 1:
|
||||
num = None
|
||||
elif len(argv) == 2:
|
||||
try:
|
||||
num = int(argv[1])
|
||||
except Exception:
|
||||
raise ValueError(
|
||||
f"{__file__} parameter must be an integer, or can be omitted"
|
||||
)
|
||||
else:
|
||||
raise RuntimeError(f"{__file__} takes one parameter at max")
|
||||
|
||||
main(num)
|
||||
|
||||
__all__ = (Song.__name__, MuchItemsSomewhere.__name__, muchBeersOnTheWall.__name__, balladOfProgrammer.__name__)
|
||||
|
|
@ -1,2 +1 @@
|
|||
as -o ab.o ab.S
|
||||
ld -o a.out ab.o
|
||||
arm-linux-gnueabi-as src.s -o src.o && arm-linux-gnueabi-gcc -static src.o -o run && qemu-arm run
|
||||
|
|
|
|||
|
|
@ -1,513 +1,27 @@
|
|||
.data
|
||||
.align 2
|
||||
.code 32
|
||||
|
||||
.section .rodata
|
||||
.align 2
|
||||
.code 32
|
||||
|
||||
overflow_msg: .ascii "Invalid number. Overflow.\n"
|
||||
overflow_msglen = . - overflow_msg
|
||||
bad_input_msg: .ascii "Invalid input. NaN.\n"
|
||||
bad_input_msglen = . - bad_input_msg
|
||||
range_err_msg: .ascii "Value out of range.\n"
|
||||
range_err_msglen = . - range_err_msg
|
||||
io_error_msg: .ascii "I/O error.\n"
|
||||
io_error_msglen = . - range_err_msg
|
||||
|
||||
sys_exit = 1
|
||||
sys_read = 3
|
||||
sys_write = 4
|
||||
max_rd_buf = 14
|
||||
lf = 10
|
||||
m10_9 = 0x3b9aca00
|
||||
maxval = 1000
|
||||
minval = -1000
|
||||
|
||||
.text
|
||||
.global main
|
||||
.extern printf
|
||||
.extern scanf
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ void main()
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type _start STT_FUNC
|
||||
.global _start
|
||||
_start:
|
||||
stmfd sp!, {r4,r5,lr}
|
||||
main:
|
||||
push {lr}
|
||||
ldr r0, =scanf_lit
|
||||
ldr r1, =num_a
|
||||
ldr r2, =num_b
|
||||
bl scanf // scanf("%d %d", &num_a, &num_b);
|
||||
ldr r0, =printf_lit
|
||||
ldr r1, =num_a
|
||||
ldr r1, [r1]
|
||||
ldr r2, =num_b
|
||||
ldr r2, [r2]
|
||||
add r1, r1, r2
|
||||
bl printf // printf("%d\n", num_a + num_b);
|
||||
pop {pc}
|
||||
|
||||
.read_lhs:
|
||||
ldr r0, =max_rd_buf
|
||||
bl readint
|
||||
mov r4, r0
|
||||
bl printint
|
||||
mov r0, r4
|
||||
bl range_check
|
||||
|
||||
.read_rhs:
|
||||
ldr r0, =max_rd_buf
|
||||
bl readint
|
||||
mov r5, r0
|
||||
bl printint
|
||||
mov r0, r5
|
||||
bl range_check
|
||||
|
||||
.sum_and_print:
|
||||
adds r0, r4, r5
|
||||
bvs overflow
|
||||
bl printint
|
||||
|
||||
.main_exit:
|
||||
mov r0, #0
|
||||
bl exit
|
||||
ldmfd sp!, {r4,r5,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ Read from stdin until we encounter a non-digit, or we have read bytes2rd digits.
|
||||
@@ Ignore leading spaces.
|
||||
@@ Return value to the caller converted to a signed int.
|
||||
@@ We read positive values, but if we read a leading '-' sign, we convert the
|
||||
@@ return value to two's complement.
|
||||
@@ The argument is max number of bytes to read from stdin.
|
||||
@@ int readint(int bytes2rd)
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type readint STT_FUNC
|
||||
.global readint
|
||||
readint:
|
||||
stmfd sp!, {r4,r5,r6,r7,lr}
|
||||
@@@@@@@@@@@@@@@
|
||||
@@ r0 : #0 for stdin arg to read.
|
||||
@@ r1 : ptr to current pos in local buffer.
|
||||
@@ r2 : #1 to read one byte at a time.
|
||||
@@ r3,r7 : tmp.
|
||||
@@ r4 : number of bytes read.
|
||||
@@ r5 : value of current byte.
|
||||
@@ r6 : 0 while we are reading leading spaces.
|
||||
@@@@@@@@@@@@@@@
|
||||
sub sp, sp, r0
|
||||
mov r1, sp
|
||||
mov r3, #0
|
||||
push {r3} @ sp,#4: local var @isnegative. return in r1. Default value is 0/false. Positive number.
|
||||
push {r0} @ sp,#0: local var @maxbytes. const.
|
||||
mov r2, #1
|
||||
mov r4, #0
|
||||
|
||||
mov r6, #0
|
||||
b .rd
|
||||
@ we get here if r6 is 0.
|
||||
@ if space, goto .rd.
|
||||
@ else set r6 to 1 and goto .noleading.
|
||||
.leadchk:
|
||||
mov r0, r5
|
||||
bl isspace
|
||||
cmp r0, #1
|
||||
beq .rd
|
||||
|
||||
.sign_chk:
|
||||
mov r0, r5
|
||||
push {r1}
|
||||
bl issign
|
||||
cmp r0, #1
|
||||
streq r0, [sp,#8] @ sp,#4 + 4 for the pushed r1.
|
||||
movhi r1, #0
|
||||
strhi r1, [sp,#8] @ sp,#4 + 4 for the pushed r1.
|
||||
pop {r1}
|
||||
bhs .rd
|
||||
|
||||
mov r6, #1
|
||||
b .noleading
|
||||
|
||||
.rd:
|
||||
mov r0, #0
|
||||
bl read
|
||||
cmp r0, #1
|
||||
bne .sum_digits_eof @ eof
|
||||
mov r5, #0
|
||||
ldrb r5, [r1]
|
||||
cmp r6, #0
|
||||
beq .leadchk
|
||||
|
||||
.noleading:
|
||||
mov r0, r5
|
||||
bl isdigit
|
||||
cmp r0, #1
|
||||
bne .sum_digits_nan @ r5 is non-digit
|
||||
|
||||
add r4, r4, #1
|
||||
add r1, r1, #1
|
||||
@ max chars to read is received in arg[0], stored in local var at sp.
|
||||
@ Only 10 can be valid, so the default of 12 leaves space for separator.
|
||||
ldr r3, [sp]
|
||||
cmp r4, r3
|
||||
beq .sum_digits_maxrd @ max bytes read.
|
||||
b .rd
|
||||
|
||||
|
||||
@@@@@@@@@@@@@@@
|
||||
@ We have read r4 (0..arg[0](default 12)) digits when we get here. Go through them
|
||||
@ and add/mul them together to calculate a number.
|
||||
@ We multiply and add the digits in reverse order to simplify the multiplication.
|
||||
@@@@@@@@@@@@@@@
|
||||
@ r0: return value.
|
||||
@ r1: local variable for read buffer.
|
||||
@ r2: tmp for conversion.
|
||||
@ r3,r6,r7: tmp
|
||||
@ r4: number of chars we have read.
|
||||
@ r5: multiplier 1,10,100.
|
||||
@@@@@@@@@@@@@@@
|
||||
.sum_digits_nan:
|
||||
mov r0, r5
|
||||
bl isspace
|
||||
cmp r0, #1
|
||||
bne bad_input
|
||||
.sum_digits_maxrd:
|
||||
.sum_digits_eof:
|
||||
mov r0, #0
|
||||
mov r5, #1
|
||||
.count:
|
||||
cmp r4, #0
|
||||
beq .readint_ret
|
||||
sub r4, r4, #1
|
||||
sub r1, #1
|
||||
ldrb r2, [r1]
|
||||
sub r2, r2, #48
|
||||
mov r3, r2
|
||||
|
||||
@ multiply r3 (char value of digit) with r5 (multiplier).
|
||||
@ possible overflow.
|
||||
@ MI means negative.
|
||||
@ smulls multiples two signed 32 bit vals and returns a 64 bit result.
|
||||
@ If we get anything in r7, the value has overflowed.
|
||||
@ having r2[31] set is overflow too.
|
||||
smulls r2, r7, r3, r5
|
||||
cmp r7, #0
|
||||
bne overflow
|
||||
cmp r2, #0
|
||||
bmi overflow
|
||||
|
||||
@@ possible overflow.
|
||||
adds r0, r0, r2
|
||||
bvs overflow
|
||||
bmi overflow
|
||||
|
||||
@@ end of array check.
|
||||
@@ check is needed here too, for large numbers, since 10 billion is not a valid 32 bit val.
|
||||
cmp r4, #0
|
||||
beq .readint_ret
|
||||
|
||||
@@ multiple multiplier by 10.
|
||||
@@ possible overflow.
|
||||
@@ too many digits is input. happens if input is more than 10 digits.
|
||||
mov r3, #10
|
||||
mov r6, r5
|
||||
smulls r5, r7, r3, r6
|
||||
cmp r7, #0
|
||||
bne overflow
|
||||
cmp r5, #0
|
||||
bmi overflow
|
||||
b .count
|
||||
|
||||
.readint_ret:
|
||||
ldr r1, [sp,#4] @ read isnegative value.
|
||||
cmp r1, #0
|
||||
rsbne r0, r0, #0
|
||||
pop {r2}
|
||||
add sp, sp, #4
|
||||
add sp, sp, r2
|
||||
ldmfd sp!, {r4,r5,r6,r7,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ int isdigit(int)
|
||||
@@ #48..#57 ascii range for '0'..'9'.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type isdigit STT_FUNC
|
||||
.global isdigit
|
||||
isdigit:
|
||||
stmfd sp!, {r1,lr}
|
||||
cmp r0, #48
|
||||
blo .o_range
|
||||
cmp r0, #57
|
||||
bhi .o_range
|
||||
mov r0, #1
|
||||
ldmfd sp!, {r1,pc}
|
||||
.o_range:
|
||||
mov r0, #0
|
||||
ldmfd sp!, {r1,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ int isspace(int)
|
||||
@@ ascii space = 32, tab = 9, newline 10, cr = 13.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type isspace STT_FUNC
|
||||
.global isspace
|
||||
isspace:
|
||||
stmfd sp!, {lr}
|
||||
cmp r0, #32
|
||||
cmpne r0, #9
|
||||
cmpne r0, #10
|
||||
cmpne r0, #13
|
||||
beq .is_space
|
||||
mov r0, #0
|
||||
ldmfd sp!, {pc}
|
||||
.is_space:
|
||||
mov r0, #1
|
||||
ldmfd sp!, {pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ Return value is 1 for '-' 2 for '+'.
|
||||
@@ int isspace(int)
|
||||
@@ '+' = 43 and '-' = 45.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type issign STT_FUNC
|
||||
.global issign
|
||||
issign:
|
||||
stmfd sp!, {lr}
|
||||
cmp r0, #43
|
||||
beq .plus_sign
|
||||
cmp r0, #45
|
||||
beq .minus_sign
|
||||
mov r0, #0
|
||||
ldmfd sp!, {pc}
|
||||
.plus_sign:
|
||||
mov r0, #2
|
||||
ldmfd sp!, {pc}
|
||||
.minus_sign:
|
||||
mov r0, #1
|
||||
ldmfd sp!, {pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ ARGS:
|
||||
@@ r0 : in out arg (current int value)
|
||||
@@ r1 : in out arg (ptr to current pos in buffer)
|
||||
@@ r2 : in arg (const increment. 1000_000_000, 100_000_000, 10_000_000, 1000_000, 100_000, 10_000, 1000, 100, 10, 1.)
|
||||
@@
|
||||
@@ r4 : tmp local. Outer scope must init to #10 and count down to #0.
|
||||
@@ Special case is INTMAX. Must init to 5 if r4 >= 1000_000_000 (0x3b9aca00 = m10_9).
|
||||
@@ r5: tmp
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type get_digit STT_FUNC
|
||||
.global get_digit
|
||||
get_digit:
|
||||
stmfd sp!, {r2,r4,r5,lr}
|
||||
ldr r5, =m10_9
|
||||
cmp r2, r5
|
||||
movlo r4, #10
|
||||
movhs r4, #5
|
||||
.get_digit_loop:
|
||||
sub r4, #1
|
||||
mul r5, r4, r2
|
||||
cmp r0, r5
|
||||
blo .get_digit_loop
|
||||
sub r0, r5
|
||||
add r4, r4, #48
|
||||
strb r4, [r1], #1
|
||||
ldmfd sp!, {r2,r4,r5,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ A quick way to divide (numbers evenly divisible by 10) by 10.
|
||||
@@ Most ARM cpus don't have a divide instruction,
|
||||
@@ so this will always work.
|
||||
@@ A generic div function is long and not needed here.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.div_r2_10:
|
||||
stmfd sp!, {r0,r1,r3,lr}
|
||||
mov r0, #1
|
||||
mov r1, #10
|
||||
.find_x:
|
||||
mul r3, r0, r1;
|
||||
cmp r3, r2
|
||||
movlo r0, r3
|
||||
blo .find_x
|
||||
mov r2, r0
|
||||
ldmfd sp!, {r0,r1,r3,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.print_neg_sign:
|
||||
stmfd sp!, {r0,r1,r2,lr}
|
||||
@ 45 = '-'
|
||||
mov r1, #45
|
||||
push {r1}
|
||||
mov r2, #1
|
||||
@ r1 is ptr to our local variable (holding '-').
|
||||
mov r1, sp
|
||||
mov r0, #1
|
||||
bl write
|
||||
cmp r0, #0
|
||||
blne io_error
|
||||
pop {r1}
|
||||
ldmfd sp!, {r0,r1,r2,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ void printint(int val)
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type printint STT_FUNC
|
||||
.global printint
|
||||
printint:
|
||||
stmfd sp!, {r4,r5,r6,lr}
|
||||
mov r1, #1
|
||||
ands r1, r1, r0, LSR #31
|
||||
rsbne r0, r0, #0
|
||||
blne .print_neg_sign
|
||||
sub sp, sp, #20
|
||||
mov r1, sp
|
||||
mov r3, sp
|
||||
|
||||
ldr r2, =m10_9
|
||||
.getc_loop:
|
||||
bl get_digit
|
||||
cmp r2, #1
|
||||
beq .exit_getc_loop
|
||||
bl .div_r2_10
|
||||
b .getc_loop
|
||||
.exit_getc_loop:
|
||||
ldr r0, =lf
|
||||
strb r0, [r1], #1
|
||||
|
||||
sub r2, r1, r3
|
||||
mov r1, r3
|
||||
mov r0, #1
|
||||
bl write
|
||||
cmp r0, #0
|
||||
blne io_error
|
||||
add sp, sp, #20
|
||||
ldmfd sp!, {r4,r5,r6,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
range_check:
|
||||
stmfd sp!, {r4,r5,lr}
|
||||
ldr r4, =minval
|
||||
ldr r5, =maxval
|
||||
cmp r4, #0
|
||||
cmpeq r5, #0
|
||||
beq .skip_range_check
|
||||
cmp r0, r4
|
||||
bllt range_err
|
||||
cmp r0, r5
|
||||
blgt range_err
|
||||
.skip_range_check:
|
||||
ldmfd sp!, {r4,r5,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ void range_err()
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
range_err:
|
||||
stmfd sp!, {lr}
|
||||
ldr r2, =range_err_msglen
|
||||
ldr r1, =range_err_msg
|
||||
mov r0, #2
|
||||
bl write
|
||||
mov r0, #-1
|
||||
bl exit
|
||||
ldmfd sp!, {pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ void overflow()
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
overflow:
|
||||
stmfd sp!, {lr}
|
||||
ldr r2, =overflow_msglen
|
||||
ldr r1, =overflow_msg
|
||||
mov r0, #2
|
||||
bl write
|
||||
mov r0, #-1
|
||||
bl exit
|
||||
ldmfd sp!, { pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ void bad_input()
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
bad_input:
|
||||
stmfd sp!, {lr}
|
||||
ldr r2, =bad_input_msglen
|
||||
ldr r1, =bad_input_msg
|
||||
mov r0, #2
|
||||
bl write
|
||||
mov r0, #-1
|
||||
bl exit
|
||||
ldmfd sp!, {pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ void io_error()
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
io_error:
|
||||
stmfd sp!, {lr}
|
||||
ldr r2, =io_error_msglen
|
||||
ldr r1, =io_error_msg
|
||||
mov r0, #2
|
||||
bl write
|
||||
mov r0, #-1
|
||||
bl exit
|
||||
ldmfd sp!, {pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ void exit(int)
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type _start STT_FUNC
|
||||
.global exit
|
||||
exit:
|
||||
stmfd sp!, {r7, lr}
|
||||
ldr r7, =sys_exit
|
||||
svc #0
|
||||
ldmfd sp!, {r7, pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ int write(int fd,char*buf,int len)
|
||||
@ Return 0 if we successfully write all bytes. Otherwise return the error code.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type _start STT_FUNC
|
||||
.global write
|
||||
write:
|
||||
stmfd sp!, {r4,r7, lr}
|
||||
mov r4, r2
|
||||
.wr_loop:
|
||||
ldr r7, =sys_write
|
||||
svc #0
|
||||
@ If r0 is negative, it is more than r4 with LO (unsigned <).
|
||||
cmp r0, r4
|
||||
sublo r4, r0
|
||||
blo .wr_loop
|
||||
moveq r0, #0
|
||||
ldmfd sp!, {r4,r7, pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ int read(int fd,char*buf,int len)
|
||||
@ Return number of bytes successfully read. Ignore errors.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type _start STT_FUNC
|
||||
.global read
|
||||
read:
|
||||
stmfd sp!, {r7, lr}
|
||||
ldr r7, =sys_read
|
||||
svc #0
|
||||
cmp r0, #0
|
||||
movlt r0, #0
|
||||
ldmfd sp!, {r7, pc}
|
||||
.data
|
||||
scanf_lit: .asciz "%d %d"
|
||||
printf_lit: .asciz "%d\n"
|
||||
.align 4
|
||||
.bss
|
||||
num_a: .skip 4
|
||||
num_b: .skip 4
|
||||
|
|
|
|||
2
Task/A+B/ARM-Assembly/a+b-3.arm
Normal file
2
Task/A+B/ARM-Assembly/a+b-3.arm
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
as -o ab.o ab.S
|
||||
ld -o a.out ab.o
|
||||
513
Task/A+B/ARM-Assembly/a+b-4.arm
Normal file
513
Task/A+B/ARM-Assembly/a+b-4.arm
Normal file
|
|
@ -0,0 +1,513 @@
|
|||
.data
|
||||
.align 2
|
||||
.code 32
|
||||
|
||||
.section .rodata
|
||||
.align 2
|
||||
.code 32
|
||||
|
||||
overflow_msg: .ascii "Invalid number. Overflow.\n"
|
||||
overflow_msglen = . - overflow_msg
|
||||
bad_input_msg: .ascii "Invalid input. NaN.\n"
|
||||
bad_input_msglen = . - bad_input_msg
|
||||
range_err_msg: .ascii "Value out of range.\n"
|
||||
range_err_msglen = . - range_err_msg
|
||||
io_error_msg: .ascii "I/O error.\n"
|
||||
io_error_msglen = . - range_err_msg
|
||||
|
||||
sys_exit = 1
|
||||
sys_read = 3
|
||||
sys_write = 4
|
||||
max_rd_buf = 14
|
||||
lf = 10
|
||||
m10_9 = 0x3b9aca00
|
||||
maxval = 1000
|
||||
minval = -1000
|
||||
|
||||
.text
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ void main()
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type _start STT_FUNC
|
||||
.global _start
|
||||
_start:
|
||||
stmfd sp!, {r4,r5,lr}
|
||||
|
||||
.read_lhs:
|
||||
ldr r0, =max_rd_buf
|
||||
bl readint
|
||||
mov r4, r0
|
||||
bl printint
|
||||
mov r0, r4
|
||||
bl range_check
|
||||
|
||||
.read_rhs:
|
||||
ldr r0, =max_rd_buf
|
||||
bl readint
|
||||
mov r5, r0
|
||||
bl printint
|
||||
mov r0, r5
|
||||
bl range_check
|
||||
|
||||
.sum_and_print:
|
||||
adds r0, r4, r5
|
||||
bvs overflow
|
||||
bl printint
|
||||
|
||||
.main_exit:
|
||||
mov r0, #0
|
||||
bl exit
|
||||
ldmfd sp!, {r4,r5,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ Read from stdin until we encounter a non-digit, or we have read bytes2rd digits.
|
||||
@@ Ignore leading spaces.
|
||||
@@ Return value to the caller converted to a signed int.
|
||||
@@ We read positive values, but if we read a leading '-' sign, we convert the
|
||||
@@ return value to two's complement.
|
||||
@@ The argument is max number of bytes to read from stdin.
|
||||
@@ int readint(int bytes2rd)
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type readint STT_FUNC
|
||||
.global readint
|
||||
readint:
|
||||
stmfd sp!, {r4,r5,r6,r7,lr}
|
||||
@@@@@@@@@@@@@@@
|
||||
@@ r0 : #0 for stdin arg to read.
|
||||
@@ r1 : ptr to current pos in local buffer.
|
||||
@@ r2 : #1 to read one byte at a time.
|
||||
@@ r3,r7 : tmp.
|
||||
@@ r4 : number of bytes read.
|
||||
@@ r5 : value of current byte.
|
||||
@@ r6 : 0 while we are reading leading spaces.
|
||||
@@@@@@@@@@@@@@@
|
||||
sub sp, sp, r0
|
||||
mov r1, sp
|
||||
mov r3, #0
|
||||
push {r3} @ sp,#4: local var @isnegative. return in r1. Default value is 0/false. Positive number.
|
||||
push {r0} @ sp,#0: local var @maxbytes. const.
|
||||
mov r2, #1
|
||||
mov r4, #0
|
||||
|
||||
mov r6, #0
|
||||
b .rd
|
||||
@ we get here if r6 is 0.
|
||||
@ if space, goto .rd.
|
||||
@ else set r6 to 1 and goto .noleading.
|
||||
.leadchk:
|
||||
mov r0, r5
|
||||
bl isspace
|
||||
cmp r0, #1
|
||||
beq .rd
|
||||
|
||||
.sign_chk:
|
||||
mov r0, r5
|
||||
push {r1}
|
||||
bl issign
|
||||
cmp r0, #1
|
||||
streq r0, [sp,#8] @ sp,#4 + 4 for the pushed r1.
|
||||
movhi r1, #0
|
||||
strhi r1, [sp,#8] @ sp,#4 + 4 for the pushed r1.
|
||||
pop {r1}
|
||||
bhs .rd
|
||||
|
||||
mov r6, #1
|
||||
b .noleading
|
||||
|
||||
.rd:
|
||||
mov r0, #0
|
||||
bl read
|
||||
cmp r0, #1
|
||||
bne .sum_digits_eof @ eof
|
||||
mov r5, #0
|
||||
ldrb r5, [r1]
|
||||
cmp r6, #0
|
||||
beq .leadchk
|
||||
|
||||
.noleading:
|
||||
mov r0, r5
|
||||
bl isdigit
|
||||
cmp r0, #1
|
||||
bne .sum_digits_nan @ r5 is non-digit
|
||||
|
||||
add r4, r4, #1
|
||||
add r1, r1, #1
|
||||
@ max chars to read is received in arg[0], stored in local var at sp.
|
||||
@ Only 10 can be valid, so the default of 12 leaves space for separator.
|
||||
ldr r3, [sp]
|
||||
cmp r4, r3
|
||||
beq .sum_digits_maxrd @ max bytes read.
|
||||
b .rd
|
||||
|
||||
|
||||
@@@@@@@@@@@@@@@
|
||||
@ We have read r4 (0..arg[0](default 12)) digits when we get here. Go through them
|
||||
@ and add/mul them together to calculate a number.
|
||||
@ We multiply and add the digits in reverse order to simplify the multiplication.
|
||||
@@@@@@@@@@@@@@@
|
||||
@ r0: return value.
|
||||
@ r1: local variable for read buffer.
|
||||
@ r2: tmp for conversion.
|
||||
@ r3,r6,r7: tmp
|
||||
@ r4: number of chars we have read.
|
||||
@ r5: multiplier 1,10,100.
|
||||
@@@@@@@@@@@@@@@
|
||||
.sum_digits_nan:
|
||||
mov r0, r5
|
||||
bl isspace
|
||||
cmp r0, #1
|
||||
bne bad_input
|
||||
.sum_digits_maxrd:
|
||||
.sum_digits_eof:
|
||||
mov r0, #0
|
||||
mov r5, #1
|
||||
.count:
|
||||
cmp r4, #0
|
||||
beq .readint_ret
|
||||
sub r4, r4, #1
|
||||
sub r1, #1
|
||||
ldrb r2, [r1]
|
||||
sub r2, r2, #48
|
||||
mov r3, r2
|
||||
|
||||
@ multiply r3 (char value of digit) with r5 (multiplier).
|
||||
@ possible overflow.
|
||||
@ MI means negative.
|
||||
@ smulls multiples two signed 32 bit vals and returns a 64 bit result.
|
||||
@ If we get anything in r7, the value has overflowed.
|
||||
@ having r2[31] set is overflow too.
|
||||
smulls r2, r7, r3, r5
|
||||
cmp r7, #0
|
||||
bne overflow
|
||||
cmp r2, #0
|
||||
bmi overflow
|
||||
|
||||
@@ possible overflow.
|
||||
adds r0, r0, r2
|
||||
bvs overflow
|
||||
bmi overflow
|
||||
|
||||
@@ end of array check.
|
||||
@@ check is needed here too, for large numbers, since 10 billion is not a valid 32 bit val.
|
||||
cmp r4, #0
|
||||
beq .readint_ret
|
||||
|
||||
@@ multiple multiplier by 10.
|
||||
@@ possible overflow.
|
||||
@@ too many digits is input. happens if input is more than 10 digits.
|
||||
mov r3, #10
|
||||
mov r6, r5
|
||||
smulls r5, r7, r3, r6
|
||||
cmp r7, #0
|
||||
bne overflow
|
||||
cmp r5, #0
|
||||
bmi overflow
|
||||
b .count
|
||||
|
||||
.readint_ret:
|
||||
ldr r1, [sp,#4] @ read isnegative value.
|
||||
cmp r1, #0
|
||||
rsbne r0, r0, #0
|
||||
pop {r2}
|
||||
add sp, sp, #4
|
||||
add sp, sp, r2
|
||||
ldmfd sp!, {r4,r5,r6,r7,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ int isdigit(int)
|
||||
@@ #48..#57 ascii range for '0'..'9'.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type isdigit STT_FUNC
|
||||
.global isdigit
|
||||
isdigit:
|
||||
stmfd sp!, {r1,lr}
|
||||
cmp r0, #48
|
||||
blo .o_range
|
||||
cmp r0, #57
|
||||
bhi .o_range
|
||||
mov r0, #1
|
||||
ldmfd sp!, {r1,pc}
|
||||
.o_range:
|
||||
mov r0, #0
|
||||
ldmfd sp!, {r1,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ int isspace(int)
|
||||
@@ ascii space = 32, tab = 9, newline 10, cr = 13.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type isspace STT_FUNC
|
||||
.global isspace
|
||||
isspace:
|
||||
stmfd sp!, {lr}
|
||||
cmp r0, #32
|
||||
cmpne r0, #9
|
||||
cmpne r0, #10
|
||||
cmpne r0, #13
|
||||
beq .is_space
|
||||
mov r0, #0
|
||||
ldmfd sp!, {pc}
|
||||
.is_space:
|
||||
mov r0, #1
|
||||
ldmfd sp!, {pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ Return value is 1 for '-' 2 for '+'.
|
||||
@@ int isspace(int)
|
||||
@@ '+' = 43 and '-' = 45.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type issign STT_FUNC
|
||||
.global issign
|
||||
issign:
|
||||
stmfd sp!, {lr}
|
||||
cmp r0, #43
|
||||
beq .plus_sign
|
||||
cmp r0, #45
|
||||
beq .minus_sign
|
||||
mov r0, #0
|
||||
ldmfd sp!, {pc}
|
||||
.plus_sign:
|
||||
mov r0, #2
|
||||
ldmfd sp!, {pc}
|
||||
.minus_sign:
|
||||
mov r0, #1
|
||||
ldmfd sp!, {pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ ARGS:
|
||||
@@ r0 : in out arg (current int value)
|
||||
@@ r1 : in out arg (ptr to current pos in buffer)
|
||||
@@ r2 : in arg (const increment. 1000_000_000, 100_000_000, 10_000_000, 1000_000, 100_000, 10_000, 1000, 100, 10, 1.)
|
||||
@@
|
||||
@@ r4 : tmp local. Outer scope must init to #10 and count down to #0.
|
||||
@@ Special case is INTMAX. Must init to 5 if r4 >= 1000_000_000 (0x3b9aca00 = m10_9).
|
||||
@@ r5: tmp
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type get_digit STT_FUNC
|
||||
.global get_digit
|
||||
get_digit:
|
||||
stmfd sp!, {r2,r4,r5,lr}
|
||||
ldr r5, =m10_9
|
||||
cmp r2, r5
|
||||
movlo r4, #10
|
||||
movhs r4, #5
|
||||
.get_digit_loop:
|
||||
sub r4, #1
|
||||
mul r5, r4, r2
|
||||
cmp r0, r5
|
||||
blo .get_digit_loop
|
||||
sub r0, r5
|
||||
add r4, r4, #48
|
||||
strb r4, [r1], #1
|
||||
ldmfd sp!, {r2,r4,r5,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ A quick way to divide (numbers evenly divisible by 10) by 10.
|
||||
@@ Most ARM cpus don't have a divide instruction,
|
||||
@@ so this will always work.
|
||||
@@ A generic div function is long and not needed here.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.div_r2_10:
|
||||
stmfd sp!, {r0,r1,r3,lr}
|
||||
mov r0, #1
|
||||
mov r1, #10
|
||||
.find_x:
|
||||
mul r3, r0, r1;
|
||||
cmp r3, r2
|
||||
movlo r0, r3
|
||||
blo .find_x
|
||||
mov r2, r0
|
||||
ldmfd sp!, {r0,r1,r3,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.print_neg_sign:
|
||||
stmfd sp!, {r0,r1,r2,lr}
|
||||
@ 45 = '-'
|
||||
mov r1, #45
|
||||
push {r1}
|
||||
mov r2, #1
|
||||
@ r1 is ptr to our local variable (holding '-').
|
||||
mov r1, sp
|
||||
mov r0, #1
|
||||
bl write
|
||||
cmp r0, #0
|
||||
blne io_error
|
||||
pop {r1}
|
||||
ldmfd sp!, {r0,r1,r2,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ void printint(int val)
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type printint STT_FUNC
|
||||
.global printint
|
||||
printint:
|
||||
stmfd sp!, {r4,r5,r6,lr}
|
||||
mov r1, #1
|
||||
ands r1, r1, r0, LSR #31
|
||||
rsbne r0, r0, #0
|
||||
blne .print_neg_sign
|
||||
sub sp, sp, #20
|
||||
mov r1, sp
|
||||
mov r3, sp
|
||||
|
||||
ldr r2, =m10_9
|
||||
.getc_loop:
|
||||
bl get_digit
|
||||
cmp r2, #1
|
||||
beq .exit_getc_loop
|
||||
bl .div_r2_10
|
||||
b .getc_loop
|
||||
.exit_getc_loop:
|
||||
ldr r0, =lf
|
||||
strb r0, [r1], #1
|
||||
|
||||
sub r2, r1, r3
|
||||
mov r1, r3
|
||||
mov r0, #1
|
||||
bl write
|
||||
cmp r0, #0
|
||||
blne io_error
|
||||
add sp, sp, #20
|
||||
ldmfd sp!, {r4,r5,r6,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
range_check:
|
||||
stmfd sp!, {r4,r5,lr}
|
||||
ldr r4, =minval
|
||||
ldr r5, =maxval
|
||||
cmp r4, #0
|
||||
cmpeq r5, #0
|
||||
beq .skip_range_check
|
||||
cmp r0, r4
|
||||
bllt range_err
|
||||
cmp r0, r5
|
||||
blgt range_err
|
||||
.skip_range_check:
|
||||
ldmfd sp!, {r4,r5,pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ void range_err()
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
range_err:
|
||||
stmfd sp!, {lr}
|
||||
ldr r2, =range_err_msglen
|
||||
ldr r1, =range_err_msg
|
||||
mov r0, #2
|
||||
bl write
|
||||
mov r0, #-1
|
||||
bl exit
|
||||
ldmfd sp!, {pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ void overflow()
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
overflow:
|
||||
stmfd sp!, {lr}
|
||||
ldr r2, =overflow_msglen
|
||||
ldr r1, =overflow_msg
|
||||
mov r0, #2
|
||||
bl write
|
||||
mov r0, #-1
|
||||
bl exit
|
||||
ldmfd sp!, { pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ void bad_input()
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
bad_input:
|
||||
stmfd sp!, {lr}
|
||||
ldr r2, =bad_input_msglen
|
||||
ldr r1, =bad_input_msg
|
||||
mov r0, #2
|
||||
bl write
|
||||
mov r0, #-1
|
||||
bl exit
|
||||
ldmfd sp!, {pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ void io_error()
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
io_error:
|
||||
stmfd sp!, {lr}
|
||||
ldr r2, =io_error_msglen
|
||||
ldr r1, =io_error_msg
|
||||
mov r0, #2
|
||||
bl write
|
||||
mov r0, #-1
|
||||
bl exit
|
||||
ldmfd sp!, {pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ void exit(int)
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type _start STT_FUNC
|
||||
.global exit
|
||||
exit:
|
||||
stmfd sp!, {r7, lr}
|
||||
ldr r7, =sys_exit
|
||||
svc #0
|
||||
ldmfd sp!, {r7, pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ int write(int fd,char*buf,int len)
|
||||
@ Return 0 if we successfully write all bytes. Otherwise return the error code.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type _start STT_FUNC
|
||||
.global write
|
||||
write:
|
||||
stmfd sp!, {r4,r7, lr}
|
||||
mov r4, r2
|
||||
.wr_loop:
|
||||
ldr r7, =sys_write
|
||||
svc #0
|
||||
@ If r0 is negative, it is more than r4 with LO (unsigned <).
|
||||
cmp r0, r4
|
||||
sublo r4, r0
|
||||
blo .wr_loop
|
||||
moveq r0, #0
|
||||
ldmfd sp!, {r4,r7, pc}
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ int read(int fd,char*buf,int len)
|
||||
@ Return number of bytes successfully read. Ignore errors.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
.align 2
|
||||
.code 32
|
||||
.type _start STT_FUNC
|
||||
.global read
|
||||
read:
|
||||
stmfd sp!, {r7, lr}
|
||||
ldr r7, =sys_read
|
||||
svc #0
|
||||
cmp r0, #0
|
||||
movlt r0, #0
|
||||
ldmfd sp!, {r7, pc}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
dim a(2)
|
||||
input "Enter two numbers separated by a space?", t$
|
||||
a = explode(t$," ")
|
||||
print t$ + " " + (a[0] + a[1])
|
||||
print t$ & " " & int(a[0]) + int(a[1])
|
||||
|
|
|
|||
108
Task/A+B/EDSAC-order-code/a+b-2.edsac
Normal file
108
Task/A+B/EDSAC-order-code/a+b-2.edsac
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
[A + B for Rosetta Code.
|
||||
Read two integers and find their sum.
|
||||
EDSAC program, Initial Orders 2.]
|
||||
|
||||
[Print signed number, up to 10 digits, right-justified.
|
||||
Modification of library subroutine P7.
|
||||
55 locations, load at even address.]
|
||||
T 56 K
|
||||
GKA3FT42@A47@T31@ADE10@T31@A48@T31@SDTDH44#@NDYFLDT4DS43@TF
|
||||
H17@S17@A43@G23@UFS43@T1FV4DAFG50@SFLDUFXFOFFFSFL4FT4DA49@T31@
|
||||
A1FA43@G20@XFP1024FP610D@524D!FO46@O26@XFO46@SFL8FT4DE39@
|
||||
|
||||
[Subroutine to read signed number from input, up to 10 digits.
|
||||
Partly based on library subroutine R2. Result in 4D.
|
||||
Working registers: 0F = dump to clear acc
|
||||
1F < 0 if number starts with minus, = 0 if not.
|
||||
6D = character code, as double-word value]
|
||||
T 120 K
|
||||
G K
|
||||
A 3 F [make link for return]
|
||||
T 36 @ [plant in code; clear acc]
|
||||
H 7 @ [mult reg := 10/32]
|
||||
T 4 D [initialize result to 0]
|
||||
T 1 F [no minus sign yet]
|
||||
T 6 D [ensure 7F and sandwich bit are 0]
|
||||
[Loop until find valid first character of integer, namely
|
||||
decimal digit (char codes 0..9), plus (13), or minus (22).]
|
||||
[6] I 6 F [char code from input]
|
||||
[7] T F [clear acc; also serves as constant 10/32]
|
||||
S 6 F [load negative of char code]
|
||||
A 39 @ [add 9]
|
||||
E 24 @ [if decimal digit, out]
|
||||
A 38 @ [add 3]
|
||||
E 6 @ [if 10..12, try again]
|
||||
A 37 @ [add 1]
|
||||
E 20 @ [if plus, out with acc = 0]
|
||||
A 39 @ [add 9]
|
||||
G 6 @ [if 23..31, try again]
|
||||
S 37 @ [subtract 1]
|
||||
E 6 @ [if 14..21, try again]
|
||||
T 1 F [minus, acc = -1, store in sign]
|
||||
[Loop to read characters after first. Assumes acc = 0 here.]
|
||||
[20] I 6 F [next char from input]
|
||||
S 6 F [negative to acc]
|
||||
A 39 @ [add 9]
|
||||
G 30 @ [finished if not digit]
|
||||
[24] T F [clear acc]
|
||||
V 4 D [acc := 10/32 times partial sum]
|
||||
L 8 F [shift 5 left]
|
||||
A 6 D [add latest digit]
|
||||
T 4 D [update partial sum]
|
||||
E 20 @ [loop for next char]
|
||||
[Here when no more digits]
|
||||
[30] T F [clear acc]
|
||||
A 1 F [load sign of result]
|
||||
E 36 @ [exit (with acc = 0) if >= 0]
|
||||
T F [< 0, clear acc]
|
||||
S 4 D [subtract number]
|
||||
T 4 D [store back negated; clear acc]
|
||||
[36] E F [exit with acc = 0 (EDSAC convention)]
|
||||
[Constants]
|
||||
[37] P D [1]
|
||||
[38] P 1 D [3]
|
||||
[39] P 4 D [9]
|
||||
|
||||
[Main routine]
|
||||
T 200 K
|
||||
G K
|
||||
[Variables]
|
||||
[0] P F P F [integer A]
|
||||
[2] P F P F [integer B]
|
||||
[Constants]
|
||||
[4] # F [figures]
|
||||
[5] @ F [carriage return]
|
||||
[6] & F [line feed]
|
||||
[7] K 4096 F [null char]
|
||||
[Enter with acc = 0]
|
||||
[8] O 4 @ [set teleprinter to figures]
|
||||
A 9 @
|
||||
G 120 F [read integer A from input]
|
||||
A 4 D [load]
|
||||
U #@ [save]
|
||||
T D [to 0D for printing]
|
||||
A 14 @
|
||||
G 56 F [print A]
|
||||
O 5 @ [followed by new line]
|
||||
O 6 @
|
||||
A 18 @
|
||||
G 120 F [read integer B from input]
|
||||
A 4 D [load]
|
||||
U 2#@ [save]
|
||||
T D [to 0D for printing]
|
||||
A 23 @
|
||||
G 56 F [print B]
|
||||
O 5 @ [followed by new line]
|
||||
O 6 @
|
||||
A #@ [load A]
|
||||
A 2#@ [add B]
|
||||
T D [A + B to 0D for printing]
|
||||
A 30 @
|
||||
G 56 F [print A + B]
|
||||
O 5 @ [followed by new line]
|
||||
O 6 @
|
||||
O 7 @ [print null to flush teleprinter buffer]
|
||||
Z F [stop]
|
||||
E 8 Z
|
||||
P F
|
||||
-987.123.
|
||||
|
|
@ -2,8 +2,8 @@ import extensions;
|
|||
|
||||
public program()
|
||||
{
|
||||
var A := new Integer();
|
||||
var B := new Integer();
|
||||
var A := Integer.new();
|
||||
var B := Integer.new();
|
||||
|
||||
console.loadLine(A,B).printLine(A + B)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@ public program()
|
|||
{
|
||||
console.printLine(console.readLine()
|
||||
.split()
|
||||
.selectBy(__mssg toInt<convertorOp>[0])
|
||||
.selectBy(mssgconst toInt<convertorOp>[1])
|
||||
.summarize())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import java.util.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Sum2 {
|
||||
public static void main(String[] args) {
|
||||
|
|
|
|||
15
Task/A+B/XQuery/a+b.xquery
Normal file
15
Task/A+B/XQuery/a+b.xquery
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
(:
|
||||
Using the EXPath File Module, which is built into most XQuery processors
|
||||
by default and thus does not need to get imported. Some processors bind the
|
||||
namespace automatically, others require explicit declaration.
|
||||
:)
|
||||
|
||||
xquery version "3.1";
|
||||
|
||||
declare namespace file = 'http://expath.org/ns/file';
|
||||
|
||||
let $in := 'input.txt'
|
||||
let $out := 'output.txt'
|
||||
let $numbers := tokenize(file:read-text($in))
|
||||
let $result := xs:numeric($numbers[1]) + xs:numeric($numbers[2])
|
||||
return file:write-text($out, xs:string($result))
|
||||
|
|
@ -28,12 +28,12 @@ extension op
|
|||
|
||||
public program()
|
||||
{
|
||||
var blocks := new object[] {"BO", "XK", "DQ", "CP", "NA",
|
||||
var blocks := new string[]{"BO", "XK", "DQ", "CP", "NA",
|
||||
"GT", "RE", "TG", "QD", "FS",
|
||||
"JW", "HU", "VI", "AN", "OB",
|
||||
"ER", "FS", "LY", "PC", "ZM"};
|
||||
|
||||
var words := new object[] {"", "A", "BARK", "BOOK", "TREAT", "COMMON", "SQUAD", "Confuse"};
|
||||
var words := new string[]{"", "A", "BARK", "BOOK", "TREAT", "COMMON", "SQUAD", "Confuse"};
|
||||
|
||||
Enumerator e := words.enumerator();
|
||||
e.next();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using Printf
|
||||
|
||||
function abc(str::AbstractString, list)
|
||||
isempty(str) && return true
|
||||
for i in eachindex(list)
|
||||
|
|
|
|||
|
|
@ -7,15 +7,15 @@ blocks= 'BO XK DQ CP NA GT RE TG QD FS JW HU VI AN OB ER FS LY
|
|||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
spell: procedure expose blocks; arg x /*ARG uppercases the word to be spelt.*/
|
||||
L=length(x); @.=0 /*get length of the word to be spelt. */
|
||||
do try=1 for L; z=blocks; upper z /*use a fresh copy of the "Z" blocks.*/
|
||||
do n=1 for L; y=substr(x, n, 1) /*attempt another letter in the word. */
|
||||
@.n=pos(y, z, 1 + @.n); if @.n==0 then leave /*not found? Try again*/
|
||||
z=overlay(' ', z, @.n) /*mutate the toy block ───► a onesy. */
|
||||
do q=1 for words(z); if length(word(z, q))==1 then z=delword(z, q, 1)
|
||||
L= length(x); @.= 0 /*get length of the word to be spelt. */
|
||||
do try=1 for L; z= blocks; upper z /*use a fresh copy of the "Z" blocks.*/
|
||||
do n=1 for L; y= substr(x, n, 1) /*attempt another letter in the word. */
|
||||
@.n= pos(y, z, 1 + @.n); if @.n==0 then leave /*not found? Try again*/
|
||||
z= overlay(' ', z, @.n) /*mutate the toy block ───► a onesy. */
|
||||
do q=1 for words(z); if length(word(z,q))==1 then z= delword(z, q, 1)
|
||||
end /*q*/ /* [↑] elide any existing onesy block.*/
|
||||
if n==L then leave try /*was last letter used in the spelling?*/
|
||||
end /*n*/ /* [↑] end of a toy block usage. */
|
||||
end /*try*/ /* [↑] end of a "TRY" permute. */
|
||||
say right(arg(1), 30) right( word( "can't can", (n==L) +1), 6) 'be spelt.'
|
||||
say right( arg(1), 30) right( word( "can't can", (n==L) + 1), 6) 'be spelt.'
|
||||
return
|
||||
|
|
|
|||
29
Task/ABC-Problem/XPL0/abc-problem.xpl0
Normal file
29
Task/ABC-Problem/XPL0/abc-problem.xpl0
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
string 0;
|
||||
|
||||
char Side1, Side2;
|
||||
def Size = 20;
|
||||
char Avail(Size);
|
||||
|
||||
func CanMakeWord(Word); \returns 'true' if blocks can make Word
|
||||
char Word;
|
||||
int I, Let;
|
||||
[Let:= Word(0) & $5F; \get letter and make sure it's uppercase
|
||||
if Let = 0 then return true; \if 0 then end of word; return successful
|
||||
for I:= 0 to Size-1 do \scan for block that contains letter
|
||||
if Avail(I) and (Side1(I) = Let or Side2(I) = Let) then
|
||||
[Avail(I):= false;
|
||||
if CanMakeWord(Word+1) then return true;
|
||||
];
|
||||
return false;
|
||||
];
|
||||
|
||||
int I, J, Words;
|
||||
[Side1:= "BXDCNGRTQFJHVAOEFLPZ";
|
||||
Side2:= "OKQPATEGDSWUINBRSYCM";
|
||||
Words:= ["A", "bark", "Book", "Treat", "Common", "Squad", "conFuse"];
|
||||
for J:= 0 to 6 do
|
||||
[Text(0, "Can make ^""); Text(0, Words(J)); Text(0, "^": ");
|
||||
for I:= 0 to Size-1 do Avail(I):= true;
|
||||
Text(0, if CanMakeWord(Words(J)) then "True" else "False"); CrLf(0);
|
||||
];
|
||||
]
|
||||
88
Task/AKS-test-for-primes/Ada/aks-test-for-primes.ada
Normal file
88
Task/AKS-test-for-primes/Ada/aks-test-for-primes.ada
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
with Ada.Text_IO;
|
||||
|
||||
procedure Test_For_Primes is
|
||||
|
||||
type Pascal_Triangle_Type is array (Natural range <>) of Long_Long_Integer;
|
||||
|
||||
function Calculate_Pascal_Triangle (N : in Natural) return Pascal_Triangle_Type is
|
||||
Pascal_Triangle : Pascal_Triangle_Type (0 .. N);
|
||||
begin
|
||||
Pascal_Triangle (0) := 1;
|
||||
for I in Pascal_Triangle'First .. Pascal_Triangle'Last - 1 loop
|
||||
Pascal_Triangle (1 + I) := 1;
|
||||
for J in reverse 1 .. I loop
|
||||
Pascal_Triangle (J) := Pascal_Triangle (J - 1) - Pascal_Triangle (J);
|
||||
end loop;
|
||||
Pascal_Triangle (0) := -Pascal_Triangle (0);
|
||||
end loop;
|
||||
return Pascal_Triangle;
|
||||
end Calculate_Pascal_Triangle;
|
||||
|
||||
function Is_Prime (N : Integer) return Boolean is
|
||||
I : Integer;
|
||||
Result : Boolean := True;
|
||||
Pascal_Triangle : constant Pascal_Triangle_Type := Calculate_Pascal_Triangle (N);
|
||||
begin
|
||||
I := N / 2;
|
||||
while Result and I > 1 loop
|
||||
Result := Result and Pascal_Triangle (I) mod Long_Long_Integer (N) = 0;
|
||||
I := I - 1;
|
||||
end loop;
|
||||
return Result;
|
||||
end Is_Prime;
|
||||
|
||||
function Image (N : in Long_Long_Integer;
|
||||
Sign : in Boolean := False) return String is
|
||||
Image : constant String := N'Image;
|
||||
begin
|
||||
if N < 0 then
|
||||
return Image;
|
||||
else
|
||||
if Sign then
|
||||
return "+" & Image (Image'First + 1 .. Image'Last);
|
||||
else
|
||||
return Image (Image'First + 1 .. Image'Last);
|
||||
end if;
|
||||
end if;
|
||||
end Image;
|
||||
|
||||
procedure Show (Triangle : in Pascal_Triangle_Type) is
|
||||
use Ada.Text_IO;
|
||||
Begin
|
||||
for I in reverse Triangle'Range loop
|
||||
Put (Image (Triangle (I), Sign => True));
|
||||
Put ("x^");
|
||||
Put (Image (Long_Long_Integer (I)));
|
||||
Put (" ");
|
||||
end loop;
|
||||
end Show;
|
||||
|
||||
procedure Show_Pascal_Triangles is
|
||||
use Ada.Text_IO;
|
||||
begin
|
||||
for N in 0 .. 9 loop
|
||||
declare
|
||||
Pascal_Triangle : constant Pascal_Triangle_Type := Calculate_Pascal_Triangle (N);
|
||||
begin
|
||||
Put ("(x-1)^" & Image (Long_Long_Integer (N)) & " = ");
|
||||
Show (Pascal_Triangle);
|
||||
New_Line;
|
||||
end;
|
||||
end loop;
|
||||
end Show_Pascal_Triangles;
|
||||
|
||||
procedure Show_Primes is
|
||||
use Ada.Text_IO;
|
||||
begin
|
||||
for N in 2 .. 63 loop
|
||||
if Is_Prime (N) then
|
||||
Put (N'Image);
|
||||
end if;
|
||||
end loop;
|
||||
New_Line;
|
||||
end Show_Primes;
|
||||
|
||||
begin
|
||||
Show_Pascal_Triangles;
|
||||
Show_Primes;
|
||||
end Test_For_Primes;
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
using Printf
|
||||
|
||||
function stringpoly(n::Int64)
|
||||
if n < 0
|
||||
return ""
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use std::iter::repeat;
|
||||
|
||||
fn aks_coefficients(k: usize) -> Vec<i64> {
|
||||
let mut coefficients = repeat(0i64).take(k + 1).collect::<Vec<_>>();
|
||||
let mut coefficients = vec![0i64; k + 1];
|
||||
coefficients[0] = 1;
|
||||
for i in 1..(k + 1) {
|
||||
coefficients[i] = -(1..i).fold(coefficients[0], |prev, j|{
|
||||
|
|
@ -18,7 +16,7 @@ fn is_prime(p: usize) -> bool {
|
|||
false
|
||||
} else {
|
||||
let c = aks_coefficients(p);
|
||||
(1 .. (c.len() - 1) / 2 + 1).all(|i| (c[i] % (p as i64)) == 0)
|
||||
(1..p / 2 + 1).all(|i| c[i] % p as i64 == 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -26,7 +24,7 @@ fn main() {
|
|||
for i in 0..8 {
|
||||
println!("{}: {:?}", i, aks_coefficients(i));
|
||||
}
|
||||
for i in (1..51).filter(|&i| is_prime(i)) {
|
||||
for i in (1..=50).filter(|&i| is_prime(i)) {
|
||||
print!("{} ", i);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,3 +9,5 @@ It is important not to confuse this ''abstractness'' (of implementation) with on
|
|||
In some languages, like for example in Objective Caml which is strongly statically typed, it is also possible to have '''abstract types''' that are not OO related and are not an abstractness too. These are ''pure abstract types'' without any definition even in the implementation and can be used for example for the type algebra, or for some consistence of the type inference. For example in this area, an abstract type can be used as a phantom type to augment another type as its parameter. <!-- An OCaml Guru would explain this better than me, a poor beginner... -->
|
||||
|
||||
'''Task''': show how an abstract type can be declared in the language. If the language makes a distinction between interfaces and partially implemented types illustrate both.
|
||||
|
||||
{{omit from|MiniZinc|no ability to declare new types at all}}
|
||||
|
|
|
|||
29
Task/Abstract-type/Go/abstract-type-2.go
Normal file
29
Task/Abstract-type/Go/abstract-type-2.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Beast interface {
|
||||
Cry() string
|
||||
}
|
||||
|
||||
type Pet struct{}
|
||||
type Cat struct {
|
||||
Pet
|
||||
}
|
||||
|
||||
func (p Pet) Name(b Beast) {
|
||||
fmt.Println(b.Cry())
|
||||
}
|
||||
func (p Pet) Cry() string {
|
||||
return "Woof"
|
||||
}
|
||||
func (c Cat) Cry() string {
|
||||
return "Meow"
|
||||
}
|
||||
|
||||
func main() {
|
||||
p := Pet{}
|
||||
c := Cat{}
|
||||
p.Name(p) // prt Woof
|
||||
c.Name(c) // prt Meow
|
||||
}
|
||||
29
Task/Abstract-type/Vala/abstract-type.vala
Normal file
29
Task/Abstract-type/Vala/abstract-type.vala
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
public abstract class Animal : Object {
|
||||
public void eat() {
|
||||
print("Chomp! Chomp!\n");
|
||||
}
|
||||
|
||||
public abstract void talk();
|
||||
}
|
||||
|
||||
public class Mouse : Animal {
|
||||
public override void talk() {
|
||||
print("Squeak! Squeak!\n");
|
||||
}
|
||||
}
|
||||
|
||||
public class Dog : Animal {
|
||||
public override void talk() {
|
||||
print("Woof! Woof!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
Dog mike = new Dog();
|
||||
Mouse scott = new Mouse();
|
||||
|
||||
mike.talk();
|
||||
mike.eat();
|
||||
scott.talk();
|
||||
scott.eat();
|
||||
}
|
||||
|
|
@ -2,29 +2,26 @@ with Ada.Text_IO, Generic_Divisors;
|
|||
|
||||
procedure ADB_Classification is
|
||||
function Same(P: Positive) return Positive is (P);
|
||||
|
||||
package Divisor_Sum is new Generic_Divisors
|
||||
(Result_Type => Natural, None => 0, One => Same, Add => "+");
|
||||
|
||||
type Class_Type is (Deficient, Perfect, Abundant);
|
||||
|
||||
function Class(D_Sum, N: Natural) return Class_Type is
|
||||
(if D_Sum < N then Deficient
|
||||
elsif D_Sum = N then Perfect
|
||||
else Abundant);
|
||||
|
||||
Cls: Class_Type;
|
||||
Results: array (Class_Type) of Natural := (others => 0);
|
||||
Sum: Natural;
|
||||
|
||||
package NIO is new Ada.Text_IO.Integer_IO(Natural);
|
||||
package CIO is new Ada.Text_IO.Enumeration_IO(Class_Type);
|
||||
begin
|
||||
for N in 1 .. 20_000 loop
|
||||
Sum := Divisor_Sum.Process(N);
|
||||
if Sum < N then
|
||||
Results(Deficient) := Results(Deficient)+1;
|
||||
elsif Sum = N then
|
||||
Results(Perfect) := Results(Perfect)+1;
|
||||
else
|
||||
Results(Abundant) := Results(Abundant)+1;
|
||||
end if;
|
||||
Cls := Class(Divisor_Sum.Process(N), N);
|
||||
Results(Cls) := Results(Cls)+1;
|
||||
end loop;
|
||||
Sum := 0;
|
||||
for Class in Results'Range loop
|
||||
CIO.Put(Class, 12);
|
||||
NIO.Put(Results(Class), 8);
|
||||
|
|
@ -32,7 +29,7 @@ begin
|
|||
end loop;
|
||||
Ada.Text_IO.Put_Line("--------------------");
|
||||
Ada.Text_IO.Put("Sum ");
|
||||
NIO.Put(Sum, 8);
|
||||
NIO.Put(Results(Deficient)+Results(Perfect)+Results(Abundant), 8);
|
||||
Ada.Text_IO.New_Line;
|
||||
Ada.Text_IO.Put_Line("====================");
|
||||
end ADB_Classification;
|
||||
|
|
|
|||
|
|
@ -6,15 +6,15 @@ divs(1) -> [];
|
|||
divs(N) -> lists:sort(divisors(1,N)).
|
||||
|
||||
divisors(1,N) ->
|
||||
[1] ++ divisors(2,N,math:sqrt(N)).
|
||||
divisors(2,N,math:sqrt(N),[1]).
|
||||
|
||||
divisors(K,_N,Q) when K > Q -> [];
|
||||
divisors(K,N,_Q) when N rem K =/= 0 ->
|
||||
[] ++ divisors(K+1,N,math:sqrt(N));
|
||||
divisors(K,N,_Q) when K * K == N ->
|
||||
[K] ++ divisors(K+1,N,math:sqrt(N));
|
||||
divisors(K,N,_Q) ->
|
||||
[K, N div K] ++ divisors(K+1,N,math:sqrt(N)).
|
||||
divisors(K,_N,Q,L) when K > Q -> L;
|
||||
divisors(K,N,_Q,L) when N rem K =/= 0 ->
|
||||
divisors(K+1,N,_Q,L);
|
||||
divisors(K,N,_Q,L) when K * K =:= N ->
|
||||
divisors(K+1,N,_Q,[K|L]);
|
||||
divisors(K,N,_Q,L) ->
|
||||
divisors(K+1,N,_Q,[N div K, K|L]).
|
||||
|
||||
sumdivs(N) -> lists:sum(divs(N)).
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
d = new dict
|
||||
for n = 1 to 20000
|
||||
{
|
||||
s = sum[allFactors[n, true, false, true], 0]
|
||||
rel = s <=> n
|
||||
d.increment[rel, 1]
|
||||
}
|
||||
|
||||
println["Deficient: " + d@(-1)]
|
||||
println["Perfect: " + d@0]
|
||||
println["Abundant: " + d@1]
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import Data.Numbers.Primes (primeFactors)
|
||||
import Data.List (group, sort)
|
||||
import Data.Bool (bool)
|
||||
|
||||
deficientPerfectAbundantCountsUpTo :: Int -> (Int, Int, Int)
|
||||
deficientPerfectAbundantCountsUpTo n =
|
||||
foldr
|
||||
(\x (deficient, perfect, abundant) ->
|
||||
let divisorSum = sum $ properDivisors x
|
||||
in bool
|
||||
(bool
|
||||
(deficient, succ perfect, abundant)
|
||||
(deficient, perfect, succ abundant)
|
||||
(divisorSum > x))
|
||||
(succ deficient, perfect, abundant)
|
||||
(divisorSum < x))
|
||||
(0, 0, 0)
|
||||
[1 .. n :: Int]
|
||||
|
||||
properDivisors :: Int -> [Int]
|
||||
properDivisors =
|
||||
init . sort . foldr (
|
||||
flip ((<*>) . fmap (*)) . scanl (*) 1
|
||||
) [1] . group . primeFactors
|
||||
|
||||
main :: IO ()
|
||||
main = print $ deficientPerfectAbundantCountsUpTo 20000
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
'''Abundant, deficient and perfect number classifications'''
|
||||
|
||||
from itertools import accumulate, chain, groupby, product
|
||||
from functools import reduce
|
||||
from math import floor, sqrt
|
||||
from operator import mul
|
||||
|
||||
|
||||
# deficientPerfectAbundantCountsUpTo :: Int -> (Int, Int, Int)
|
||||
def deficientPerfectAbundantCountsUpTo(n):
|
||||
'''Counts of deficient, perfect, and abundant
|
||||
integers in the range [1..n].
|
||||
'''
|
||||
def go(dpa, x):
|
||||
deficient, perfect, abundant = dpa
|
||||
divisorSum = sum(properDivisors(x))
|
||||
return (
|
||||
succ(deficient), perfect, abundant
|
||||
) if x > divisorSum else (
|
||||
deficient, perfect, succ(abundant)
|
||||
) if x < divisorSum else (
|
||||
deficient, succ(perfect), abundant
|
||||
)
|
||||
return reduce(go, range(1, 1 + n), (0, 0, 0))
|
||||
|
||||
|
||||
# --------------------------TEST--------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Size of each sub-class of integers drawn from [1..20000]:'''
|
||||
|
||||
print(main.__doc__)
|
||||
print(
|
||||
'\n'.join(map(
|
||||
lambda a, b: a.rjust(10) + ' -> ' + str(b),
|
||||
['Deficient', 'Perfect', 'Abundant'],
|
||||
deficientPerfectAbundantCountsUpTo(20000)
|
||||
))
|
||||
)
|
||||
|
||||
|
||||
# ------------------------GENERIC-------------------------
|
||||
|
||||
# primeFactors :: Int -> [Int]
|
||||
def primeFactors(n):
|
||||
'''A list of the prime factors of n.
|
||||
'''
|
||||
def f(qr):
|
||||
r = qr[1]
|
||||
return step(r), 1 + r
|
||||
|
||||
def step(x):
|
||||
return 1 + (x << 2) - ((x >> 1) << 1)
|
||||
|
||||
def go(x):
|
||||
root = floor(sqrt(x))
|
||||
|
||||
def p(qr):
|
||||
q = qr[0]
|
||||
return root < q or 0 == (x % q)
|
||||
|
||||
q = until(p)(f)(
|
||||
(2 if 0 == x % 2 else 3, 1)
|
||||
)[0]
|
||||
return [x] if q > root else [q] + go(x // q)
|
||||
|
||||
return go(n)
|
||||
|
||||
|
||||
# properDivisors :: Int -> [Int]
|
||||
def properDivisors(n):
|
||||
'''The ordered divisors of n, excluding n itself.
|
||||
'''
|
||||
def go(a, x):
|
||||
return [a * b for a, b in product(
|
||||
a,
|
||||
accumulate(chain([1], x), mul)
|
||||
)]
|
||||
return sorted(
|
||||
reduce(go, [
|
||||
list(g) for _, g in groupby(primeFactors(n))
|
||||
], [1])
|
||||
)[:-1] if 1 < n else []
|
||||
|
||||
|
||||
# succ :: Int -> Int
|
||||
def succ(x):
|
||||
'''The successor of a value.
|
||||
For numeric types, (1 +).
|
||||
'''
|
||||
return 1 + x
|
||||
|
||||
|
||||
# until :: (a -> Bool) -> (a -> a) -> a -> a
|
||||
def until(p):
|
||||
'''The result of repeatedly applying f until p holds.
|
||||
The initial seed value is x.
|
||||
'''
|
||||
def go(f, x):
|
||||
v = x
|
||||
while not p(v):
|
||||
v = f(v)
|
||||
return v
|
||||
return lambda f: lambda x: go(f, x)
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# nthArrow :: (a -> b) -> Tuple -> Int -> Tuple
|
||||
def nthArrow(f):
|
||||
'''A simple function lifted to one which applies to a
|
||||
tuple, transforming only its nth value.
|
||||
'''
|
||||
def go(v, n):
|
||||
m = n - 1
|
||||
return v if n > len(v) else [
|
||||
x if m != i else f(x) for i, x in enumerate(v)
|
||||
]
|
||||
return lambda tpl: lambda n: tuple(go(tpl, n))
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# deficientPerfectAbundantCountsUpTo :: Int -> (Int, Int, Int)
|
||||
def deficientPerfectAbundantCountsUpTo(n):
|
||||
'''Counts of deficient, perfect, and abundant
|
||||
integers in the range [1..n].
|
||||
'''
|
||||
def go(dpa, x):
|
||||
divisorSum = sum(properDivisors(x))
|
||||
return nthArrow(succ)(dpa)(
|
||||
1 if x > divisorSum else (
|
||||
3 if x < divisorSum else 2
|
||||
)
|
||||
)
|
||||
return reduce(go, range(1, 1 + n), (0, 0, 0))
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
enum Classification {
|
||||
DEFICIENT,
|
||||
PERFECT,
|
||||
ABUNDANT
|
||||
}
|
||||
|
||||
void main() {
|
||||
var i = 0; var j = 0;
|
||||
var sum = 0; var try_max = 0;
|
||||
int[] count_list = {1, 0, 0};
|
||||
for (i = 2; i <= 20000; i++) {
|
||||
try_max = i / 2;
|
||||
sum = 1;
|
||||
for (j = 2; j < try_max; j++) {
|
||||
if (i % j != 0)
|
||||
continue;
|
||||
try_max = i / j;
|
||||
sum += j;
|
||||
if (j != try_max)
|
||||
sum += try_max;
|
||||
}
|
||||
if (sum < i) {
|
||||
count_list[Classification.DEFICIENT]++;
|
||||
continue;
|
||||
}
|
||||
if (sum > i) {
|
||||
count_list[Classification.ABUNDANT]++;
|
||||
continue;
|
||||
}
|
||||
count_list[Classification.PERFECT]++;
|
||||
}
|
||||
print(@"There are $(count_list[Classification.DEFICIENT]) deficient,");
|
||||
print(@" $(count_list[Classification.PERFECT]) perfect,");
|
||||
print(@" $(count_list[Classification.ABUNDANT]) abundant numbers between 1 and 20000.\n");
|
||||
}
|
||||
2
Task/Accumulator-factory/Retro/accumulator-factory.retro
Normal file
2
Task/Accumulator-factory/Retro/accumulator-factory.retro
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
:acc (ns-)
|
||||
d:create , [ [ fetch ] [ v:inc ] bi ] does ;
|
||||
|
|
@ -15,8 +15,10 @@ The Ackermann function is usually defined as follows:
|
|||
|
||||
<!-- <table><tr><td width=12><td><td><math>n+1</math><td>if <math>m=0</math> <tr><td> <td><math>A(m, n) =</math> <td><math>A(m-1, 1)</math> <td>if <math>m>0</math> and <math>n=0</math> <tr><td><td><td><math>A(m-1, A(m, n-1))</math> <td> if <math>m>0</math> and <math>n>0</math></table> -->
|
||||
|
||||
Its arguments are never negative and it always terminates. Write a function which returns the value of <math>A(m, n)</math>. Arbitrary precision is preferred (since the function grows so quickly), but not required.
|
||||
Its arguments are never negative and it always terminates.
|
||||
|
||||
;Task:
|
||||
Write a function which returns the value of <math>A(m, n)</math>. Arbitrary precision is preferred (since the function grows so quickly), but not required.
|
||||
|
||||
;See also:
|
||||
* [[wp:Conway_chained_arrow_notation#Ackermann_function|Conway chained arrow notation]] for the Ackermann function.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
function ack(M,N) {
|
||||
for (; M > 0; M--) {
|
||||
N = N === 0 ? 1 : ack(M,N-1);
|
||||
}
|
||||
return N+1;
|
||||
}
|
||||
20
Task/Ackermann-function/JavaScript/ackermann-function-3.js
Normal file
20
Task/Ackermann-function/JavaScript/ackermann-function-3.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
function stackermann(M, N) {
|
||||
const stack = [];
|
||||
for (;;) {
|
||||
if (M === 0) {
|
||||
N++;
|
||||
if (stack.length === 0) return N;
|
||||
const r = stack[stack.length-1];
|
||||
if (r[1] === 1) stack.length--;
|
||||
else r[1]--;
|
||||
M = r[0];
|
||||
} else if (N === 0) {
|
||||
M--;
|
||||
N = 1;
|
||||
} else {
|
||||
M--
|
||||
stack.push([M, N]);
|
||||
N = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Task/Ackermann-function/JavaScript/ackermann-function-4.js
Normal file
26
Task/Ackermann-function/JavaScript/ackermann-function-4.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env nodejs
|
||||
function ack(M, N){
|
||||
const next = new Float64Array(M + 1);
|
||||
const goal = new Float64Array(M + 1).fill(1, 0, M);
|
||||
const n = N + 1;
|
||||
|
||||
// This serves as a sentinel value;
|
||||
// next[M] never equals goal[M] == -1,
|
||||
// so we don't need an extra check for
|
||||
// loop termination below.
|
||||
goal[M] = -1;
|
||||
|
||||
let v;
|
||||
do {
|
||||
v = next[0] + 1;
|
||||
let m = 0;
|
||||
while (next[m] === goal[m]) {
|
||||
goal[m] = v;
|
||||
next[m++]++;
|
||||
}
|
||||
next[m]++;
|
||||
} while (next[M] !== n);
|
||||
return v;
|
||||
}
|
||||
var args = process.argv;
|
||||
console.log(ack(parseInt(args[2]), parseInt(args[3])));
|
||||
38
Task/Ackermann-function/JavaScript/ackermann-function-5.js
Normal file
38
Task/Ackermann-function/JavaScript/ackermann-function-5.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// ackermann :: Int -> Int -> Int
|
||||
const ackermann = m => n => {
|
||||
const go = (m, n) =>
|
||||
0 === m ? (
|
||||
succ(n)
|
||||
) : go(pred(m), 0 === n ? (
|
||||
1
|
||||
) : go(m, pred(n)));
|
||||
return go(m, n);
|
||||
};
|
||||
|
||||
// TEST -----------------------------------------------
|
||||
const main = () => console.log(JSON.stringify(
|
||||
[0, 1, 2, 3].map(
|
||||
flip(ackermann)(3)
|
||||
)
|
||||
));
|
||||
|
||||
|
||||
// GENERAL FUNCTIONS ----------------------------------
|
||||
|
||||
// flip :: (a -> b -> c) -> b -> a -> c
|
||||
const flip = f =>
|
||||
x => y => f(y)(x);
|
||||
|
||||
// pred :: Enum a => a -> a
|
||||
const pred = x => x - 1;
|
||||
|
||||
// succ :: Enum a => a -> a
|
||||
const succ = x => 1 + x;
|
||||
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
38
Task/Ackermann-function/Lua/ackermann-function-2.lua
Normal file
38
Task/Ackermann-function/Lua/ackermann-function-2.lua
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env luajit
|
||||
local gmp = require 'gmp' ('libgmp')
|
||||
local mpz, z_mul, z_add, z_add_ui, z_set_d =
|
||||
gmp.types.z, gmp.z_mul, gmp.z_add, gmp.z_add_ui, gmp.z_set_d
|
||||
local z_cmp, z_cmp_ui, z_init_d, z_set=
|
||||
gmp.z_cmp, gmp.z_cmp_ui, gmp.z_init_set_d, gmp.z_set
|
||||
local printf = gmp.printf
|
||||
|
||||
local function ack(i,n)
|
||||
local nxt=setmetatable({}, {__index=function(t,k) local z=mpz() z_init_d(z, 0) t[k]=z return z end})
|
||||
local goal=setmetatable({}, {__index=function(t,k) local o=mpz() z_init_d(o, 1) t[k]=o return o end})
|
||||
goal[i]=mpz() z_init_d(goal[i], -1)
|
||||
local v=mpz() z_init_d(v, 0)
|
||||
local ic
|
||||
local END=n+1
|
||||
local ntmp,gtmp
|
||||
repeat
|
||||
ic=0
|
||||
ntmp,gtmp=nxt[ic], goal[ic]
|
||||
z_add_ui(v, ntmp, 1)
|
||||
while z_cmp(ntmp, gtmp) == 0 do
|
||||
z_set(gtmp,v)
|
||||
z_add_ui(ntmp, ntmp, 1)
|
||||
nxt[ic], goal[ic]=ntmp, gtmp
|
||||
ic=ic+1
|
||||
ntmp,gtmp=nxt[ic], goal[ic]
|
||||
end
|
||||
z_add_ui(ntmp, ntmp, 1)
|
||||
nxt[ic]=ntmp
|
||||
until z_cmp_ui(nxt[i], END) == 0
|
||||
return v
|
||||
end
|
||||
|
||||
if #arg<1 then
|
||||
print("Ackermann: "..arg[0].." <num1> [num2]")
|
||||
else
|
||||
printf("%Zd\n", ack(tonumber(arg[1]), arg[2] and tonumber(arg[2]) or 0))
|
||||
end
|
||||
|
|
@ -1,9 +1,19 @@
|
|||
int ackermann(int m, n)
|
||||
{
|
||||
if (m == 0)
|
||||
return n + 1;
|
||||
else if (m > 0 && n == 0)
|
||||
return ackermann(m - 1, 1);
|
||||
else
|
||||
return ackermann( m - 1, ackermann(m, n - 1) );
|
||||
int ackermann(int m, int n) {
|
||||
if (m == 0)
|
||||
return n + 1;
|
||||
else if (m > 0 && n == 0)
|
||||
return ackermann(m - 1, 1);
|
||||
else
|
||||
return ackermann( m - 1, ackermann(m, n - 1) );
|
||||
}
|
||||
|
||||
// Call function to produce output:
|
||||
// the first 4x7 Ackermann numbers
|
||||
void setup() {
|
||||
for (int m=0; m<4; m++) {
|
||||
for (int n=0; n<7; n++) {
|
||||
print(ackermann(m, n), " ");
|
||||
}
|
||||
println();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
13
Task/Ackermann-function/Vala/ackermann-function.vala
Normal file
13
Task/Ackermann-function/Vala/ackermann-function.vala
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
uint64 ackermann(uint64 m, uint64 n) {
|
||||
if (m == 0) return n + 1;
|
||||
if (n == 0) return ackermann(m - 1, 1);
|
||||
return ackermann(m - 1, ackermann(m, n - 1));
|
||||
}
|
||||
|
||||
void main () {
|
||||
for (uint64 m = 0; m < 4; ++m) {
|
||||
for (uint64 n = 0; n < 10; ++n) {
|
||||
print(@"A($m,$n) = $(ackermann(m,n))\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Task/Ackermann-function/X86-Assembly/ackermann-function.x86
Normal file
29
Task/Ackermann-function/X86-Assembly/ackermann-function.x86
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
section .text
|
||||
|
||||
global _main
|
||||
_main:
|
||||
mov eax, 3 ;m
|
||||
mov ebx, 4 ;n
|
||||
call ack ;returns number in ebx
|
||||
ret
|
||||
|
||||
ack:
|
||||
cmp eax, 0
|
||||
je M0 ;if M == 0
|
||||
cmp ebx, 0
|
||||
je N0 ;if N == 0
|
||||
dec ebx ;else N-1
|
||||
push eax ;save M
|
||||
call ack1 ;ack(m,n) -> returned in ebx so no further instructions needed
|
||||
pop eax ;restore M
|
||||
dec eax ;M - 1
|
||||
call ack1 ;return ack(m-1,ack(m,n-1))
|
||||
ret
|
||||
M0:
|
||||
inc ebx ;return n + 1
|
||||
ret
|
||||
N0:
|
||||
dec eax
|
||||
inc ebx ;ebx always 0: inc -> ebx = 1
|
||||
call ack1 ;return ack(M-1,1)
|
||||
ret
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
Import-Module ActiveDirectory
|
||||
|
||||
$searchData = "user name"
|
||||
$searchBase = "DC=example,DC=com"
|
||||
|
||||
#searches by some of the most common unique identifiers
|
||||
get-aduser -Filter((DistinguishedName -eq $searchdata) -or (UserPrincipalName -eq $searchdata) -or (SamAccountName -eq $searchdata)) -SearchBase $searchBase
|
||||
65
Task/Active-object/Phix/active-object-1.phix
Normal file
65
Task/Active-object/Phix/active-object-1.phix
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
integer xlock = init_cs()
|
||||
|
||||
class integrator
|
||||
--
|
||||
-- Integrates input function f over time
|
||||
-- v + (t1 - t0) * (f(t1) + f(t0)) / 2
|
||||
--
|
||||
integer f -- function f(atom t); (see note)
|
||||
atom interval, t0, k0 = 0, v = 0
|
||||
bool running
|
||||
public integer id
|
||||
|
||||
procedure set_func(integer rid)
|
||||
this.f = rid
|
||||
end procedure
|
||||
|
||||
procedure update()
|
||||
enter_cs(xlock)
|
||||
integer f = this.f -- (nb: no "this")
|
||||
atom t1 = time(),
|
||||
k1 = f(t1)
|
||||
-- (oops, '+=' not yet properly supported on class fields...)
|
||||
-- v += (t1 - t0) * (k1 + k0) / 2
|
||||
v = v + (t1 - t0) * (k1 + k0) / 2
|
||||
t0 = t1
|
||||
k0 = k1
|
||||
leave_cs(xlock)
|
||||
end procedure
|
||||
|
||||
procedure tick()
|
||||
running = true
|
||||
while running do
|
||||
sleep(interval)
|
||||
update()
|
||||
end while
|
||||
end procedure
|
||||
|
||||
procedure stop()
|
||||
running = false
|
||||
wait_thread(id)
|
||||
end procedure
|
||||
|
||||
function get_output()
|
||||
return v
|
||||
end function
|
||||
|
||||
end class
|
||||
|
||||
function new_integrator(integer rid, atom interval)
|
||||
integrator i = new({rid,interval,time()})
|
||||
i.update()
|
||||
i.id = create_thread(i.tick,{i})
|
||||
return i
|
||||
end function
|
||||
|
||||
function zero(atom /*t*/) return 0 end function
|
||||
function sine(atom t) return sin(2*PI*0.5*t) end function
|
||||
|
||||
integrator i = new_integrator(sine,0.01);
|
||||
sleep(2)
|
||||
?i.get_output()
|
||||
i.set_func(zero)
|
||||
sleep(0.5)
|
||||
i.stop()
|
||||
?i.get_output()
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
julia> x = 3
|
||||
julia> x = [1, 2, 3]
|
||||
julia> ptr = pointer_from_objref(x)
|
||||
Ptr{Void} @0x000000010282e4a0
|
||||
julia> unsafe_pointer_to_objref(ptr)
|
||||
3
|
||||
3-element Array{Int64,1}:
|
||||
1
|
||||
2
|
||||
3
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
use Scalar::Util qw(refaddr);
|
||||
print refaddr(\my $v), "\n"; # 135691508
|
||||
print refaddr(\my $v), "\n"; # 140502490125712
|
||||
|
|
|
|||
|
|
@ -1,4 +1 @@
|
|||
my $a = 12;
|
||||
my $b = \$a; # get reference
|
||||
$$b = $$b + 30; # access referenced value
|
||||
print $a; # prints 42
|
||||
printf "%p", $v; # 7fc949039590
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
my $a = 12;
|
||||
our $b; # you can overlay only global variables (this line is only for strictness)
|
||||
*b = \$a;
|
||||
print $b; # prints 12
|
||||
$b++;
|
||||
print $a; # prints 13
|
||||
my $b = \$a; # get reference
|
||||
$$b = $$b + 30; # access referenced value
|
||||
print $a; # prints 42
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
my $a = 12;
|
||||
our $b; # you can overlay only global variables (this line is only for strictness)
|
||||
*b = \$a;
|
||||
print $b; # prints 12
|
||||
$b++;
|
||||
print $a; # prints 13
|
||||
9
Task/Address-of-a-variable/R/address-of-a-variable-1.r
Normal file
9
Task/Address-of-a-variable/R/address-of-a-variable-1.r
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
x <- 5
|
||||
y <- x
|
||||
pryr::address(x)
|
||||
pryr::address(y)
|
||||
|
||||
y <- y + 1
|
||||
|
||||
pryr::address(x)
|
||||
pryr::address(y)
|
||||
12
Task/Address-of-a-variable/R/address-of-a-variable-2.r
Normal file
12
Task/Address-of-a-variable/R/address-of-a-variable-2.r
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
address <- function(obj) {
|
||||
paste0("0x", substring(sub(" .*$","",capture.output(.Internal(inspect(obj)))),2))
|
||||
}
|
||||
|
||||
x <- 5
|
||||
y <- x
|
||||
address(x)
|
||||
address(y)
|
||||
|
||||
y <- y + 1
|
||||
address(x)
|
||||
address(y)
|
||||
|
|
@ -1,45 +1,19 @@
|
|||
from StringIO import StringIO
|
||||
from itertools import zip_longest
|
||||
|
||||
textinfile = '''Given$a$text$file$of$many$lines,$where$fields$within$a$line$
|
||||
txt = """Given$a$txt$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.'''
|
||||
justified,$right$justified,$or$center$justified$within$its$column."""
|
||||
|
||||
j2justifier = dict(L=str.ljust, R=str.rjust, C=str.center)
|
||||
parts = [line.rstrip("$").split("$") for line in txt.splitlines()]
|
||||
widths = [max(len(word) for word in col)
|
||||
for col in zip_longest(*parts, fillvalue='')]
|
||||
|
||||
def aligner(infile, justification = 'L'):
|
||||
''' \
|
||||
Justify columns of textual tabular input where the row separator is the newline
|
||||
and the field separator is a 'dollar' character.
|
||||
justification can be L, R, or C; (Left, Right, or Centered).
|
||||
|
||||
Return the justified output as a string
|
||||
'''
|
||||
assert justification in j2justifier, "justification can be L, R, or C; (Left, Right, or Centered)."
|
||||
justifier = j2justifier[justification]
|
||||
|
||||
fieldsbyrow= [line.strip().split('$') for line in infile]
|
||||
# pad to same number of fields per row
|
||||
maxfields = max(len(row) for row in fieldsbyrow)
|
||||
fieldsbyrow = [fields + ['']*(maxfields - len(fields))
|
||||
for fields in fieldsbyrow]
|
||||
# rotate
|
||||
fieldsbycolumn = zip(*fieldsbyrow)
|
||||
# calculate max fieldwidth per column
|
||||
colwidths = [max(len(field) for field in column)
|
||||
for column in fieldsbycolumn]
|
||||
# pad fields in columns to colwidth with spaces
|
||||
fieldsbycolumn = [ [justifier(field, width) for field in column]
|
||||
for width, column in zip(colwidths, fieldsbycolumn) ]
|
||||
# rotate again
|
||||
fieldsbyrow = zip(*fieldsbycolumn)
|
||||
|
||||
return "\n".join( " ".join(row) for row in fieldsbyrow)
|
||||
|
||||
|
||||
for align in 'Left Right Center'.split():
|
||||
infile = StringIO(textinfile)
|
||||
print "\n# %s Column-aligned output:" % align
|
||||
print aligner(infile, align[0])
|
||||
for justify in "<_Left ^_Center >_Right".split():
|
||||
j, jtext = justify.split('_')
|
||||
print(f"{jtext} column-aligned output:\n")
|
||||
for line in parts:
|
||||
print(' '.join(f"{wrd:{j}{wdth}}" for wdth, wrd in zip(widths, line)))
|
||||
print("- " * 52)
|
||||
|
|
|
|||
|
|
@ -1,18 +1,45 @@
|
|||
'''
|
||||
cat <<'EOF' > align_columns.dat
|
||||
Given$a$text$file$of$many$lines,$where$fields$within$a$line$
|
||||
from StringIO import StringIO
|
||||
|
||||
textinfile = '''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.
|
||||
EOF
|
||||
'''
|
||||
justified,$right$justified,$or$center$justified$within$its$column.'''
|
||||
|
||||
for align in '<^>':
|
||||
rows = [ line.strip().split('$') for line in open('align_columns.dat') ]
|
||||
fmts = [ '{:%s%d}' % (align, max( len(row[i]) if i < len(row) else 0 for row in rows ))
|
||||
for i in range(max(map(len, rows))) ]
|
||||
for row in rows:
|
||||
print(' '.join(fmts).format(*(row + [''] * len(fmts))))
|
||||
print('')
|
||||
j2justifier = dict(L=str.ljust, R=str.rjust, C=str.center)
|
||||
|
||||
def aligner(infile, justification = 'L'):
|
||||
''' \
|
||||
Justify columns of textual tabular input where the row separator is the newline
|
||||
and the field separator is a 'dollar' character.
|
||||
justification can be L, R, or C; (Left, Right, or Centered).
|
||||
|
||||
Return the justified output as a string
|
||||
'''
|
||||
assert justification in j2justifier, "justification can be L, R, or C; (Left, Right, or Centered)."
|
||||
justifier = j2justifier[justification]
|
||||
|
||||
fieldsbyrow= [line.strip().split('$') for line in infile]
|
||||
# pad to same number of fields per row
|
||||
maxfields = max(len(row) for row in fieldsbyrow)
|
||||
fieldsbyrow = [fields + ['']*(maxfields - len(fields))
|
||||
for fields in fieldsbyrow]
|
||||
# rotate
|
||||
fieldsbycolumn = zip(*fieldsbyrow)
|
||||
# calculate max fieldwidth per column
|
||||
colwidths = [max(len(field) for field in column)
|
||||
for column in fieldsbycolumn]
|
||||
# pad fields in columns to colwidth with spaces
|
||||
fieldsbycolumn = [ [justifier(field, width) for field in column]
|
||||
for width, column in zip(colwidths, fieldsbycolumn) ]
|
||||
# rotate again
|
||||
fieldsbyrow = zip(*fieldsbycolumn)
|
||||
|
||||
return "\n".join( " ".join(row) for row in fieldsbyrow)
|
||||
|
||||
|
||||
for align in 'Left Right Center'.split():
|
||||
infile = StringIO(textinfile)
|
||||
print "\n# %s Column-aligned output:" % align
|
||||
print aligner(infile, align[0])
|
||||
|
|
|
|||
|
|
@ -1,21 +1,18 @@
|
|||
txt = """Given$a$txt$file$of$many$lines,$where$fields$within$a$line$
|
||||
'''
|
||||
cat <<'EOF' > align_columns.dat
|
||||
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."""
|
||||
justified,$right$justified,$or$center$justified$within$its$column.
|
||||
EOF
|
||||
'''
|
||||
|
||||
parts = [line.rstrip("$").split("$") for line in txt.splitlines()]
|
||||
|
||||
max_widths = {}
|
||||
for line in parts:
|
||||
for i, word in enumerate(line):
|
||||
max_widths[i] = max(max_widths.get(i, 0), len(word))
|
||||
|
||||
for i, justify in enumerate([str.ljust, str.center, str.rjust]):
|
||||
print ["Left", "Center", "Right"][i], " column-aligned output:\n"
|
||||
for line in parts:
|
||||
for j, word in enumerate(line):
|
||||
print justify(word, max_widths[j]),
|
||||
print
|
||||
print "- " * 52
|
||||
for align in '<^>':
|
||||
rows = [ line.strip().split('$') for line in open('align_columns.dat') ]
|
||||
fmts = [ '{:%s%d}' % (align, max( len(row[i]) if i < len(row) else 0 for row in rows ))
|
||||
for i in range(max(map(len, rows))) ]
|
||||
for row in rows:
|
||||
print(' '.join(fmts).format(*(row + [''] * len(fmts))))
|
||||
print('')
|
||||
|
|
|
|||
|
|
@ -1,75 +1,21 @@
|
|||
'''Variously aligned columns
|
||||
from delimited text.
|
||||
'''
|
||||
|
||||
from functools import reduce
|
||||
from itertools import repeat
|
||||
|
||||
|
||||
# TEST ----------------------------------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Test of three alignments.'''
|
||||
|
||||
txt = '''Given$a$text$file$of$many$lines,$where$fields$within$a$line$
|
||||
txt = """Given$a$txt$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.'''
|
||||
justified,$right$justified,$or$center$justified$within$its$column."""
|
||||
|
||||
rows = [x.split('$') for x in txt.splitlines()]
|
||||
table = paddedRows(max(map(len, rows)))('')(rows)
|
||||
parts = [line.rstrip("$").split("$") for line in txt.splitlines()]
|
||||
|
||||
print('\n\n'.join(map(
|
||||
alignedTable(table)(' '),
|
||||
[-1, 0, 1] # Left, Center, Right
|
||||
)))
|
||||
max_widths = {}
|
||||
for line in parts:
|
||||
for i, word in enumerate(line):
|
||||
max_widths[i] = max(max_widths.get(i, 0), len(word))
|
||||
|
||||
|
||||
# alignedTable :: [[String]] -> Alignment -> String -> String
|
||||
def alignedTable(rows):
|
||||
'''Tabulation of rows of cells, with cell alignment
|
||||
specified by:
|
||||
eAlign -1 = left
|
||||
eAlign 0 = center
|
||||
eAlign 1 = right
|
||||
and separator between columns
|
||||
supplied by the `sep` argument.
|
||||
'''
|
||||
def go(sep, eAlign):
|
||||
lcr = ['ljust', 'center', 'rjust'][1 + eAlign]
|
||||
|
||||
# nextAlignedCol :: [[String]] -> [String] -> [[String]]
|
||||
def nextAlignedCol(cols, col):
|
||||
w = max(len(cell) for cell in col)
|
||||
return cols + [
|
||||
[getattr(s, lcr)(w, ' ') for s in col]
|
||||
]
|
||||
|
||||
return '\n'.join([
|
||||
sep.join(cells) for cells in
|
||||
zip(*reduce(nextAlignedCol, zip(*rows), []))
|
||||
])
|
||||
return lambda sep: lambda eAlign: go(sep, eAlign)
|
||||
|
||||
|
||||
# GENERIC -------------------------------------------------
|
||||
|
||||
# paddedRows :: Int -> a -> [[a]] -> [[a]]
|
||||
def paddedRows(n):
|
||||
'''A list of rows of even length,
|
||||
in which each may be padded (but
|
||||
not truncated) to length n with
|
||||
appended copies of value v.'''
|
||||
def go(v, xs):
|
||||
def pad(x):
|
||||
d = n - len(x)
|
||||
return (x + list(repeat(v, d))) if 0 < d else x
|
||||
return [pad(row) for row in xs]
|
||||
return lambda v: lambda xs: go(v, xs) if xs else []
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
for i, justify in enumerate([str.ljust, str.center, str.rjust]):
|
||||
print(["Left", "Center", "Right"][i], " column-aligned output:\n")
|
||||
for line in parts:
|
||||
for j, word in enumerate(line):
|
||||
print(justify(word, max_widths[j]), end=' ')
|
||||
print()
|
||||
print("- " * 52)
|
||||
|
|
|
|||
75
Task/Align-columns/Python/align-columns-5.py
Normal file
75
Task/Align-columns/Python/align-columns-5.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
'''Variously aligned columns
|
||||
from delimited text.
|
||||
'''
|
||||
|
||||
from functools import reduce
|
||||
from itertools import repeat
|
||||
|
||||
|
||||
# TEST ----------------------------------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Test of three alignments.'''
|
||||
|
||||
txt = '''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.'''
|
||||
|
||||
rows = [x.split('$') for x in txt.splitlines()]
|
||||
table = paddedRows(max(map(len, rows)))('')(rows)
|
||||
|
||||
print('\n\n'.join(map(
|
||||
alignedTable(table)(' '),
|
||||
[-1, 0, 1] # Left, Center, Right
|
||||
)))
|
||||
|
||||
|
||||
# alignedTable :: [[String]] -> Alignment -> String -> String
|
||||
def alignedTable(rows):
|
||||
'''Tabulation of rows of cells, with cell alignment
|
||||
specified by:
|
||||
eAlign -1 = left
|
||||
eAlign 0 = center
|
||||
eAlign 1 = right
|
||||
and separator between columns
|
||||
supplied by the `sep` argument.
|
||||
'''
|
||||
def go(sep, eAlign):
|
||||
lcr = ['ljust', 'center', 'rjust'][1 + eAlign]
|
||||
|
||||
# nextAlignedCol :: [[String]] -> [String] -> [[String]]
|
||||
def nextAlignedCol(cols, col):
|
||||
w = max(len(cell) for cell in col)
|
||||
return cols + [
|
||||
[getattr(s, lcr)(w, ' ') for s in col]
|
||||
]
|
||||
|
||||
return '\n'.join([
|
||||
sep.join(cells) for cells in
|
||||
zip(*reduce(nextAlignedCol, zip(*rows), []))
|
||||
])
|
||||
return lambda sep: lambda eAlign: go(sep, eAlign)
|
||||
|
||||
|
||||
# GENERIC -------------------------------------------------
|
||||
|
||||
# paddedRows :: Int -> a -> [[a]] -> [[a]]
|
||||
def paddedRows(n):
|
||||
'''A list of rows of even length,
|
||||
in which each may be padded (but
|
||||
not truncated) to length n with
|
||||
appended copies of value v.'''
|
||||
def go(v, xs):
|
||||
def pad(x):
|
||||
d = n - len(x)
|
||||
return (x + list(repeat(v, d))) if 0 < d else x
|
||||
return [pad(row) for row in xs]
|
||||
return lambda v: lambda xs: go(v, xs) if xs else []
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
using Printf
|
||||
|
||||
println("Classification Tests:")
|
||||
tests = [1:12, 28, 496, 220, 1184, 12496, 1264460, 790, 909, 562, 1064, 1488]
|
||||
for i in tests
|
||||
|
|
|
|||
40
Task/Almost-prime/Delphi/almost-prime.delphi
Normal file
40
Task/Almost-prime/Delphi/almost-prime.delphi
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
program AlmostPrime;
|
||||
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
function IsKPrime(const n, k: Integer): Boolean;
|
||||
var
|
||||
p, f, v: Integer;
|
||||
begin
|
||||
f := 0;
|
||||
p := 2;
|
||||
v := n;
|
||||
while (f < k) and (p*p <= n) do begin
|
||||
while (v mod p) = 0 do begin
|
||||
v := v div p;
|
||||
Inc(f);
|
||||
end;
|
||||
Inc(p);
|
||||
end;
|
||||
if v > 1 then Inc(f);
|
||||
Result := f = k;
|
||||
end;
|
||||
|
||||
var
|
||||
i, c, k: Integer;
|
||||
|
||||
begin
|
||||
for k := 1 to 5 do begin
|
||||
Write('k = ', k, ':');
|
||||
c := 0;
|
||||
i := 2;
|
||||
while c < 10 do begin
|
||||
if IsKPrime(i, k) then begin
|
||||
Write(' ', i);
|
||||
Inc(c);
|
||||
end;
|
||||
Inc(i);
|
||||
end;
|
||||
WriteLn;
|
||||
end;
|
||||
end.
|
||||
17
Task/Almost-prime/Julia/almost-prime.julia
Normal file
17
Task/Almost-prime/Julia/almost-prime.julia
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using Primes
|
||||
|
||||
isalmostprime(n::Integer, k::Integer) = sum(values(factor(n))) == k
|
||||
|
||||
function almostprimes(N::Integer, k::Integer) # return first N almost-k primes
|
||||
P = Vector{typeof(k)}(undef,N)
|
||||
i = 0; n = 2
|
||||
while i < N
|
||||
if isalmostprime(n, k) P[i += 1] = n end
|
||||
n += 1
|
||||
end
|
||||
return P
|
||||
end
|
||||
|
||||
for k in 1:5
|
||||
println("$k-Almost-primes: ", join(almostprimes(10, k), ", "), "...")
|
||||
end
|
||||
35
Task/Almost-prime/Swift/almost-prime.swift
Normal file
35
Task/Almost-prime/Swift/almost-prime.swift
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
struct KPrimeGen: Sequence, IteratorProtocol {
|
||||
let k: Int
|
||||
private(set) var n: Int
|
||||
|
||||
private func isKPrime() -> Bool {
|
||||
var primes = 0
|
||||
var f = 2
|
||||
var rem = n
|
||||
|
||||
while primes < k && rem > 1 {
|
||||
while rem % f == 0 && rem > 1 {
|
||||
rem /= f
|
||||
primes += 1
|
||||
}
|
||||
|
||||
f += 1
|
||||
}
|
||||
|
||||
return rem == 1 && primes == k
|
||||
}
|
||||
|
||||
mutating func next() -> Int? {
|
||||
n += 1
|
||||
|
||||
while !isKPrime() {
|
||||
n += 1
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
}
|
||||
|
||||
for k in 1..<6 {
|
||||
print("\(k): \(Array(KPrimeGen(k: k, n: 1).lazy.prefix(10)))")
|
||||
}
|
||||
|
|
@ -68,7 +68,8 @@ public program()
|
|||
try
|
||||
{
|
||||
ambOperator
|
||||
.for(new {"the","that","a"},new {"frog", "elephant", "thing"},new {"walked", "treaded", "grows"}, new {"slowly", "quickly"})
|
||||
.for(new::("the","that","a"),new::("frog", "elephant", "thing"),new::("walked", "treaded", "grows"),
|
||||
new::("slowly", "quickly"))
|
||||
.seek:(a,b,c,d => joinable(a,b) && joinable(b,c) && joinable(c,d) )
|
||||
.do:(a,b,c,d) { console.printLine(a," ",b," ",c," ",d) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ example = do
|
|||
w2 <- amb ["frog", "elephant", "thing"]
|
||||
w3 <- amb ["walked", "treaded", "grows"]
|
||||
w4 <- amb ["slowly", "quickly"]
|
||||
unless (joins w1 w2) (amb [])
|
||||
unless (joins w2 w3) (amb [])
|
||||
unless (joins w3 w4) (amb [])
|
||||
return (unwords [w1, w2, w3, w4])
|
||||
guard (w1 `joins` w2)
|
||||
guard (w2 `joins` w3)
|
||||
guard (w3 `joins` w4)
|
||||
pure $ unwords [w1, w2, w3, w4]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ extension op
|
|||
var sum := divsums[i];
|
||||
^ (i < sum) && (sum < divsums.Length) && (divsums[sum] == i)
|
||||
}
|
||||
.selectBy:(i => new:{ Item1 = i; Item2 = divsums[i]; })
|
||||
.selectBy:(i => new::{ Item1 = i; Item2 = divsums[i]; })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue