Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
4
Task/Sum-to-100/00-META.yaml
Normal file
4
Task/Sum-to-100/00-META.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category:
|
||||
- Puzzles
|
||||
from: http://rosettacode.org/wiki/Sum_to_100
|
||||
31
Task/Sum-to-100/00-TASK.txt
Normal file
31
Task/Sum-to-100/00-TASK.txt
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
;Task:
|
||||
Find solutions to the <big> ''sum to one hundred'' </big> puzzle.
|
||||
|
||||
|
||||
Add (insert) the mathematical
|
||||
operators <big> '''+''' </big> or <big><big> '''-''' </big></big> (plus
|
||||
or minus) before any of the digits in the
|
||||
<br>decimal numeric string <big> '''123456789''' </big> such that the
|
||||
resulting mathematical expression adds up to a
|
||||
<br>particular sum (in this iconic case, '''100''').
|
||||
|
||||
|
||||
Example:
|
||||
<big> <big> <b> <big> 123 + 4 - 5 + 67 - 89 = 100 </big> </b> </big> </big>
|
||||
|
||||
Show all output here.
|
||||
|
||||
|
||||
:* Show all solutions that sum to <big> '''100''' </big>
|
||||
:* Show the sum that has the maximum ''number'' of solutions (from zero to infinity<sup><big>‡</big></sup>)
|
||||
:* Show the lowest positive sum that ''can't'' be expressed (has no solutions), using the rules for this task
|
||||
:* Show the ten highest numbers that can be expressed using the rules for this task (extra credit)
|
||||
<br>
|
||||
|
||||
<sup><big>‡</big></sup> (where ''infinity'' would be a relatively small 123,456,789)
|
||||
|
||||
|
||||
An example of a sum that can't be expressed (within the rules of this task) is: '''5074'''
|
||||
<br>(which, of course, isn't the lowest positive sum that can't be expressed).
|
||||
<br><br>
|
||||
|
||||
77
Task/Sum-to-100/11l/sum-to-100.11l
Normal file
77
Task/Sum-to-100/11l/sum-to-100.11l
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
-V
|
||||
NUMBER_OF_DIGITS = 9
|
||||
THREE_POW_4 = 3 * 3 * 3 * 3
|
||||
NUMBER_OF_EXPRESSIONS = 2 * THREE_POW_4 * THREE_POW_4
|
||||
|
||||
T.enum Op
|
||||
ADD
|
||||
SUB
|
||||
JOIN
|
||||
|
||||
T Expression
|
||||
code = [Op.ADD] * :NUMBER_OF_DIGITS
|
||||
|
||||
F inc()
|
||||
L(i) 0 .< .code.len
|
||||
.code[i] = Op((Int(.code[i]) + 1) % 3)
|
||||
I .code[i] != ADD
|
||||
L.break
|
||||
|
||||
F toInt()
|
||||
V value = 0
|
||||
V number = 0
|
||||
V sign = 1
|
||||
L(digit) 1..9
|
||||
V c = .code[:NUMBER_OF_DIGITS - digit]
|
||||
I c == ADD {value += sign * number; number = digit; sign = 1}
|
||||
E I c == SUB {value += sign * number; number = digit; sign = -1}
|
||||
E {number = 10 * number + digit}
|
||||
R value + sign * number
|
||||
|
||||
F String()
|
||||
V s = ‘’
|
||||
L(digit) 1 .. :NUMBER_OF_DIGITS
|
||||
V c = .code[:NUMBER_OF_DIGITS - digit]
|
||||
I c == ADD
|
||||
I digit > 1
|
||||
s ‘’= ‘ + ’
|
||||
E I c == SUB
|
||||
s ‘’= ‘ - ’
|
||||
s ‘’= String(digit)
|
||||
R s.ltrim(‘ ’)
|
||||
|
||||
F printe(givenSum)
|
||||
V expression = Expression()
|
||||
L 0 .< :NUMBER_OF_EXPRESSIONS
|
||||
I expression.toInt() == givenSum
|
||||
print(‘#9’.format(givenSum)‘ = ’expression)
|
||||
expression.inc()
|
||||
|
||||
T Stat
|
||||
DefaultDict[Int, Int] countSum
|
||||
DefaultDict[Int, Set[Int]] sumCount
|
||||
F ()
|
||||
V expression = Expression()
|
||||
L 0 .< :NUMBER_OF_EXPRESSIONS
|
||||
V sum = expression.toInt()
|
||||
.countSum[sum]++
|
||||
expression.inc()
|
||||
L(k, v) .countSum
|
||||
.sumCount[v].add(k)
|
||||
|
||||
print("100 has the following solutions:\n")
|
||||
printe(100)
|
||||
|
||||
V stat = Stat()
|
||||
V maxCount = max(stat.sumCount.keys())
|
||||
V maxSum = max(stat.sumCount[maxCount])
|
||||
print("\n#. has the maximum number of solutions, namely #.".format(maxSum, maxCount))
|
||||
|
||||
V value = 0
|
||||
L value C stat.countSum
|
||||
value++
|
||||
print("\n#. is the lowest positive number with no solutions".format(value))
|
||||
|
||||
print("\nThe ten highest numbers that do have solutions are:\n")
|
||||
L(i) sorted(stat.countSum.keys(), reverse' 1B)[0.<10]
|
||||
printe(i)
|
||||
131
Task/Sum-to-100/ALGOL-68/sum-to-100.alg
Normal file
131
Task/Sum-to-100/ALGOL-68/sum-to-100.alg
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
BEGIN
|
||||
# find the numbers the string 123456789 ( with "+/-" optionally inserted #
|
||||
# before each digit ) can generate #
|
||||
|
||||
# experimentation shows that the largest hundred numbers that can be #
|
||||
# generated are are greater than or equal to 56795 #
|
||||
# as we can't declare an array with bounds -123456789 : 123456789 in #
|
||||
# Algol 68G, we use -60000 : 60000 and keep counts for the top hundred #
|
||||
|
||||
INT max number = 60 000;
|
||||
[ - max number : max number ]STRING solutions;
|
||||
[ - max number : max number ]INT count;
|
||||
FOR i FROM LWB solutions TO UPB solutions DO solutions[ i ] := ""; count[ i ] := 0 OD;
|
||||
|
||||
# calculate the numbers ( up to max number ) we can generate and the strings leading to them #
|
||||
# also determine the largest numbers we can generate #
|
||||
[ 100 ]INT largest;
|
||||
[ 100 ]INT largest count;
|
||||
INT impossible number = - 999 999 999;
|
||||
FOR i FROM LWB largest TO UPB largest DO
|
||||
largest [ i ] := impossible number;
|
||||
largest count[ i ] := 0
|
||||
OD;
|
||||
[ 1 : 18 ]CHAR sum string := ".1.2.3.4.5.6.7.8.9";
|
||||
[]CHAR sign char = []CHAR( "-", " ", "+" )[ AT -1 ];
|
||||
# we don't distinguish between strings starting "+1" and starting " 1" #
|
||||
FOR s1 FROM -1 TO 0 DO
|
||||
sum string[ 1 ] := sign char[ s1 ];
|
||||
FOR s2 FROM -1 TO 1 DO
|
||||
sum string[ 3 ] := sign char[ s2 ];
|
||||
FOR s3 FROM -1 TO 1 DO
|
||||
sum string[ 5 ] := sign char[ s3 ];
|
||||
FOR s4 FROM -1 TO 1 DO
|
||||
sum string[ 7 ] := sign char[ s4 ];
|
||||
FOR s5 FROM -1 TO 1 DO
|
||||
sum string[ 9 ] := sign char[ s5 ];
|
||||
FOR s6 FROM -1 TO 1 DO
|
||||
sum string[ 11 ] := sign char[ s6 ];
|
||||
FOR s7 FROM -1 TO 1 DO
|
||||
sum string[ 13 ] := sign char[ s7 ];
|
||||
FOR s8 FROM -1 TO 1 DO
|
||||
sum string[ 15 ] := sign char[ s8 ];
|
||||
FOR s9 FROM -1 TO 1 DO
|
||||
sum string[ 17 ] := sign char[ s9 ];
|
||||
INT number := 0;
|
||||
INT part := IF s1 < 0 THEN -1 ELSE 1 FI;
|
||||
IF s2 = 0 THEN part *:= 10 +:= 2 * SIGN part ELSE number +:= part; part := 2 * s2 FI;
|
||||
IF s3 = 0 THEN part *:= 10 +:= 3 * SIGN part ELSE number +:= part; part := 3 * s3 FI;
|
||||
IF s4 = 0 THEN part *:= 10 +:= 4 * SIGN part ELSE number +:= part; part := 4 * s4 FI;
|
||||
IF s5 = 0 THEN part *:= 10 +:= 5 * SIGN part ELSE number +:= part; part := 5 * s5 FI;
|
||||
IF s6 = 0 THEN part *:= 10 +:= 6 * SIGN part ELSE number +:= part; part := 6 * s6 FI;
|
||||
IF s7 = 0 THEN part *:= 10 +:= 7 * SIGN part ELSE number +:= part; part := 7 * s7 FI;
|
||||
IF s8 = 0 THEN part *:= 10 +:= 8 * SIGN part ELSE number +:= part; part := 8 * s8 FI;
|
||||
IF s9 = 0 THEN part *:= 10 +:= 9 * SIGN part ELSE number +:= part; part := 9 * s9 FI;
|
||||
number +:= part;
|
||||
IF number >= LWB solutions
|
||||
AND number <= UPB solutions
|
||||
THEN
|
||||
solutions[ number ] +:= ";" + sum string;
|
||||
count [ number ] +:= 1
|
||||
FI;
|
||||
BOOL inserted := FALSE;
|
||||
FOR l pos FROM LWB largest TO UPB largest WHILE NOT inserted DO
|
||||
IF number > largest[ l pos ] THEN
|
||||
# found a new larger number #
|
||||
FOR m pos FROM UPB largest BY -1 TO l pos + 1 DO
|
||||
largest [ m pos ] := largest [ m pos - 1 ];
|
||||
largest count[ m pos ] := largest count[ m pos - 1 ]
|
||||
OD;
|
||||
largest [ l pos ] := number;
|
||||
largest count[ l pos ] := 1;
|
||||
inserted := TRUE
|
||||
ELIF number = largest[ l pos ] THEN
|
||||
# have another way of generating this number #
|
||||
largest count[ l pos ] +:= 1;
|
||||
inserted := TRUE
|
||||
FI
|
||||
OD
|
||||
OD
|
||||
OD
|
||||
OD
|
||||
OD
|
||||
OD
|
||||
OD
|
||||
OD
|
||||
OD
|
||||
OD;
|
||||
|
||||
# show the solutions for 100 #
|
||||
print( ( "100 has ", whole( count[ 100 ], 0 ), " solutions:" ) );
|
||||
STRING s := solutions[ 100 ];
|
||||
FOR s pos FROM LWB s TO UPB s DO
|
||||
IF s[ s pos ] = ";" THEN print( ( newline, " " ) )
|
||||
ELIF s[ s pos ] /= " " THEN print( ( s[ s pos ] ) )
|
||||
FI
|
||||
OD;
|
||||
print( ( newline ) );
|
||||
# find the number with the most solutions #
|
||||
INT max solutions := 0;
|
||||
INT number with max := LWB count - 1;
|
||||
FOR n FROM 0 TO max number DO
|
||||
IF count[ n ] > max solutions THEN
|
||||
max solutions := count[ n ];
|
||||
number with max := n
|
||||
FI
|
||||
OD;
|
||||
FOR n FROM LWB largest count TO UPB largest count DO
|
||||
IF largest count[ n ] > max solutions THEN
|
||||
max solutions := largest count[ n ];
|
||||
number with max := largest[ n ]
|
||||
FI
|
||||
OD;
|
||||
print( ( whole( number with max, 0 ), " has the maximum number of solutions: ", whole( max solutions, 0 ), newline ) );
|
||||
# find the smallest positive number that has no solutions #
|
||||
BOOL have solutions := TRUE;
|
||||
FOR n FROM 0 TO max number
|
||||
WHILE IF NOT ( have solutions := count[ n ] > 0 )
|
||||
THEN print( ( whole( n, 0 ), " is the lowest positive number with no solutions", newline ) )
|
||||
FI;
|
||||
have solutions
|
||||
DO SKIP OD;
|
||||
IF have solutions
|
||||
THEN print( ( "All positive numbers up to ", whole( max number, 0 ), " have solutions", newline ) )
|
||||
FI;
|
||||
print( ( "The 10 largest numbers that can be generated are:", newline ) );
|
||||
FOR t pos FROM 1 TO 10 DO
|
||||
print( ( " ", whole( largest[ t pos ], 0 ) ) )
|
||||
OD;
|
||||
print( ( newline ) )
|
||||
|
||||
END
|
||||
107
Task/Sum-to-100/AWK/sum-to-100.awk
Normal file
107
Task/Sum-to-100/AWK/sum-to-100.awk
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#
|
||||
# RossetaCode: Sum to 100, AWK.
|
||||
#
|
||||
# Find solutions to the "sum to one hundred" puzzle.
|
||||
|
||||
function evaluate(code)
|
||||
{
|
||||
value = 0
|
||||
number = 0
|
||||
power = 1
|
||||
for ( k = 9; k >= 1; k-- )
|
||||
{
|
||||
number = power*k + number
|
||||
op = code % 3
|
||||
if ( op == 0 ) {
|
||||
value = value + number
|
||||
number = 0
|
||||
power = 1
|
||||
} else if (op == 1 ) {
|
||||
value = value - number
|
||||
number = 0
|
||||
power = 1
|
||||
} else if ( op == 2) {
|
||||
power = power * 10
|
||||
} else {
|
||||
}
|
||||
code = int(code / 3);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function show(code)
|
||||
{
|
||||
s = ""
|
||||
a = 19683
|
||||
b = 6561
|
||||
|
||||
for ( k = 1; k <= 9; k++ )
|
||||
{
|
||||
op = int( (code % a) / b )
|
||||
if ( op == 0 && k > 1 )
|
||||
s = s "+"
|
||||
else if ( op == 1 )
|
||||
s = s "-"
|
||||
else {
|
||||
}
|
||||
a = b
|
||||
b = int(b / 3)
|
||||
s = s k
|
||||
}
|
||||
printf "%9d = %s\n", evaluate(code), s;
|
||||
}
|
||||
|
||||
|
||||
BEGIN {
|
||||
nexpr = 13122
|
||||
|
||||
print
|
||||
print "Show all solutions that sum to 100"
|
||||
print
|
||||
for ( i = 0; i < nexpr; i++ ) if ( evaluate(i) == 100 ) show(i);
|
||||
|
||||
print
|
||||
print "Show the sum that has the maximum number of solutions"
|
||||
print
|
||||
for ( i = 0; i < nexpr; i++ ) {
|
||||
sum = evaluate(i);
|
||||
if ( sum >= 0 )
|
||||
stat[sum]++;
|
||||
}
|
||||
best = (-1);
|
||||
for ( sum in stat )
|
||||
if ( best < stat[sum] ) {
|
||||
best = stat[sum]
|
||||
bestSum = sum
|
||||
}
|
||||
delete stat
|
||||
printf "%d has %d solutions\n", bestSum, best
|
||||
|
||||
print
|
||||
print "Show the lowest positive number that can't be expressed"
|
||||
print
|
||||
for ( i = 0; i <= 123456789; i++ ){
|
||||
for ( j = 0; j < nexpr; j++ )
|
||||
if ( i == evaluate(j) )
|
||||
break;
|
||||
if ( i != evaluate(j) )
|
||||
break;
|
||||
}
|
||||
printf "%d\n",i
|
||||
|
||||
print
|
||||
print "Show the ten highest numbers that can be expressed"
|
||||
print
|
||||
limit = 123456789 + 1;
|
||||
for ( i = 1; i <= 10; i++ )
|
||||
{
|
||||
best = 0;
|
||||
for ( j = 0; j < nexpr; j++ )
|
||||
{
|
||||
test = evaluate(j);
|
||||
if ( test < limit && test > best ) best = test;
|
||||
}
|
||||
for ( j = 0; j < nexpr; j++ ) if ( evaluate(j) == best ) show(j)
|
||||
limit = best
|
||||
}
|
||||
}
|
||||
12
Task/Sum-to-100/Ada/sum-to-100-1.ada
Normal file
12
Task/Sum-to-100/Ada/sum-to-100-1.ada
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package Sum_To is
|
||||
|
||||
generic
|
||||
with procedure Callback(Str: String; Int: Integer);
|
||||
procedure Eval;
|
||||
|
||||
generic
|
||||
Number: Integer;
|
||||
with function Print_If(Sum, Number: Integer) return Boolean;
|
||||
procedure Print(S: String; Sum: Integer);
|
||||
|
||||
end Sum_To;
|
||||
40
Task/Sum-to-100/Ada/sum-to-100-2.ada
Normal file
40
Task/Sum-to-100/Ada/sum-to-100-2.ada
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
with Ada.Text_IO, Ada.Containers.Ordered_Maps;
|
||||
|
||||
package body Sum_To is
|
||||
|
||||
procedure Eval is
|
||||
|
||||
procedure Rec_Eval(Str: String; Previous, Current, Next: Integer) is
|
||||
Next_Image: String := Integer'Image(Next);
|
||||
-- Next_Image(1) holds a blank, Next_Image(2) a digit
|
||||
|
||||
function Sign(N: Integer) return Integer is
|
||||
(if N<0 then -1 elsif N>0 then 1 else 0);
|
||||
|
||||
begin
|
||||
if Next = 10 then -- end of recursion
|
||||
Callback(Str, Previous+Current);
|
||||
else -- Next < 10
|
||||
Rec_Eval(Str & Next_Image(2), -- concatenate current and Next
|
||||
Previous, Sign(Current)*(10*abs(Current)+Next), Next+1);
|
||||
Rec_Eval(Str & "+" & Next_Image(2), -- add Next
|
||||
Previous+Current, Next, Next+1);
|
||||
Rec_Eval(Str & "-" & Next_Image(2), -- subtract Next
|
||||
Previous+Current, -Next, Next+1);
|
||||
end if;
|
||||
end Rec_Eval;
|
||||
|
||||
begin -- Eval
|
||||
Rec_Eval("1", 0, 1, 2); -- unary "+", followed by "1"
|
||||
Rec_Eval("-1", 0, -1, 2); -- unary "-", followed by "1"
|
||||
end Eval;
|
||||
|
||||
procedure Print(S: String; Sum: Integer) is
|
||||
-- print solution (S,N), if N=Number
|
||||
begin
|
||||
if Print_If(Sum, Number) then
|
||||
Ada.Text_IO.Put_Line(Integer'Image(Sum) & " = " & S & ";");
|
||||
end if;
|
||||
end Print;
|
||||
|
||||
end Sum_To;
|
||||
10
Task/Sum-to-100/Ada/sum-to-100-3.ada
Normal file
10
Task/Sum-to-100/Ada/sum-to-100-3.ada
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
with Sum_To;
|
||||
|
||||
procedure Sum_To_100 is
|
||||
|
||||
procedure Print_100 is new Sum_To.Print(100, "=");
|
||||
procedure Eval_100 is new Sum_To.Eval(Print_100);
|
||||
|
||||
begin
|
||||
Eval_100;
|
||||
end Sum_To_100;
|
||||
67
Task/Sum-to-100/Ada/sum-to-100-4.ada
Normal file
67
Task/Sum-to-100/Ada/sum-to-100-4.ada
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
with Sum_To, Ada.Containers.Ordered_Maps, Ada.Text_IO;
|
||||
use Ada.Text_IO;
|
||||
|
||||
procedure Three_Others is
|
||||
|
||||
package Num_Maps is new Ada.Containers.Ordered_Maps
|
||||
(Key_Type => Integer, Element_Type => Positive);
|
||||
use Num_Maps;
|
||||
|
||||
Map: Num_Maps.Map;
|
||||
-- global Map stores how often a sum did occur
|
||||
|
||||
procedure Insert_Solution(S: String; Sum: Integer) is
|
||||
-- inserts a solution into global Map
|
||||
use Num_Maps;
|
||||
-- use type Num_Maps.Cursor;
|
||||
Position: Cursor := Map.Find(Sum);
|
||||
begin
|
||||
if Position = No_Element then -- first solutions for Sum
|
||||
Map.Insert(Key => Sum, New_Item => 1); -- counter is 1
|
||||
else -- increase counter for Sum
|
||||
Map.Replace_Element(Position => Position,
|
||||
New_Item => (Element(Position))+1);
|
||||
end if;
|
||||
end Insert_Solution;
|
||||
|
||||
procedure Generate_Map is new Sum_To.Eval(Insert_Solution);
|
||||
|
||||
Current: Cursor; -- Points into Map
|
||||
Sum: Integer; -- current Sum of interest
|
||||
Max: Natural;
|
||||
begin
|
||||
Generate_Map;
|
||||
|
||||
-- find Sum >= 0 with maximum number of solutions
|
||||
Max := 0; -- number of solutions for Sum (so far, none)
|
||||
Current := Map.Ceiling(0); -- first element in Map with Sum >= 0
|
||||
while Has_Element(Current) loop
|
||||
if Element(Current) > Max then
|
||||
Max := Element(Current); -- the maximum of solutions, so far
|
||||
Sum := Key(Current); -- the Sum with Max solutions
|
||||
end if;
|
||||
Next(Current);
|
||||
end loop;
|
||||
Put_Line("Most frequent result:" & Integer'Image(Sum));
|
||||
Put_Line("Frequency of" & Integer'Image(Sum) & ":" &
|
||||
Integer'Image(Max));
|
||||
New_Line;
|
||||
|
||||
-- find smallest Sum >= 0 with no solution
|
||||
Sum := 0;
|
||||
while Map.Find(Sum) /= No_Element loop
|
||||
Sum := Sum + 1;
|
||||
end loop;
|
||||
Put_Line("Smallest nonnegative impossible sum:" & Integer'Image(Sum));
|
||||
New_Line;
|
||||
|
||||
-- find ten highest numbers with a solution
|
||||
Current := Map.Last; -- highest element in Map with a solution
|
||||
Put_Line("Highest sum:" & Integer'Image(Key(Current)));
|
||||
Put("Next nine:");
|
||||
for I in 1 .. 9 loop -- 9 steps backward
|
||||
Previous(Current);
|
||||
Put(Integer'Image(Key(Current)));
|
||||
end loop;
|
||||
New_Line;
|
||||
end Three_others;
|
||||
62
Task/Sum-to-100/Aime/sum-to-100.aime
Normal file
62
Task/Sum-to-100/Aime/sum-to-100.aime
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
integer b, i, j, k, l, p, s, z;
|
||||
index r, w;
|
||||
|
||||
i = 0;
|
||||
while (i < 512) {
|
||||
b = i.bcount;
|
||||
j = 0;
|
||||
while (j < 1 << b) {
|
||||
data e;
|
||||
|
||||
j += 1;
|
||||
|
||||
k = s = p = 0;
|
||||
l = j;
|
||||
z = 1;
|
||||
while (k < 9) {
|
||||
if (i & 1 << k) {
|
||||
e.append("-+"[l & 1]);
|
||||
s += p * z;
|
||||
z = (l & 1) * 2 - 1;
|
||||
l >>= 1;
|
||||
p = 0;
|
||||
}
|
||||
e.append('1' + k);
|
||||
p = p * 10 + 1 + k;
|
||||
|
||||
k += 1;
|
||||
}
|
||||
|
||||
s += p * z;
|
||||
|
||||
if (e[0] != '+') {
|
||||
if (s == 100) {
|
||||
o_(e, "\n");
|
||||
}
|
||||
|
||||
w[s] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
w.wcall(i_fix, 1, 1, r);
|
||||
|
||||
o_(r.back, "\n");
|
||||
|
||||
k = 0;
|
||||
for (+k in w) {
|
||||
if (!w.key(k + 1)) {
|
||||
o_(k + 1, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i = 10;
|
||||
for (k of w) {
|
||||
o_(k, "\n");
|
||||
if (!(i -= 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
314
Task/Sum-to-100/AppleScript/sum-to-100.applescript
Normal file
314
Task/Sum-to-100/AppleScript/sum-to-100.applescript
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
use framework "Foundation" -- for basic NSArray sort
|
||||
|
||||
property pSigns : {1, 0, -1} --> ( + | unsigned | - )
|
||||
property plst100 : {"Sums to 100:", ""}
|
||||
property plstSums : {}
|
||||
property plstSumsSorted : missing value
|
||||
property plstSumGroups : missing value
|
||||
|
||||
-- data Sign :: [ 1 | 0 | -1 ] = ( Plus | Unsigned | Minus )
|
||||
-- asSum :: [Sign] -> Int
|
||||
on asSum(xs)
|
||||
script
|
||||
on |λ|(a, sign, i)
|
||||
if sign ≠ 0 then
|
||||
{digits:{}, n:(n of a) + (sign * ((i & digits of a) as string as integer))}
|
||||
else
|
||||
{digits:{i} & (digits of a), n:n of a}
|
||||
end if
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
set rec to foldr(result, {digits:{}, n:0}, xs)
|
||||
set ds to digits of rec
|
||||
if length of ds > 0 then
|
||||
(n of rec) + (ds as string as integer)
|
||||
else
|
||||
n of rec
|
||||
end if
|
||||
end asSum
|
||||
|
||||
-- data Sign :: [ 1 | 0 | -1 ] = ( Plus | Unisigned | Minus )
|
||||
-- asString :: [Sign] -> String
|
||||
on asString(xs)
|
||||
script
|
||||
on |λ|(a, sign, i)
|
||||
set d to i as string
|
||||
if sign ≠ 0 then
|
||||
if sign > 0 then
|
||||
a & " +" & d
|
||||
else
|
||||
a & " -" & d
|
||||
end if
|
||||
else
|
||||
a & d
|
||||
end if
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
foldl(result, "", xs)
|
||||
end asString
|
||||
|
||||
-- sumsTo100 :: () -> String
|
||||
on sumsTo100()
|
||||
-- From first permutation without leading '+' (3 ^ 8) to end of universe (3 ^ 9)
|
||||
repeat with i from 6561 to 19683
|
||||
set xs to nthPermutationWithRepn(pSigns, 9, i)
|
||||
if asSum(xs) = 100 then set end of plst100 to asString(xs)
|
||||
end repeat
|
||||
intercalate(linefeed, plst100)
|
||||
end sumsTo100
|
||||
|
||||
|
||||
-- mostCommonSum :: () -> String
|
||||
on mostCommonSum()
|
||||
-- From first permutation without leading '+' (3 ^ 8) to end of universe (3 ^ 9)
|
||||
repeat with i from 6561 to 19683
|
||||
set intSum to asSum(nthPermutationWithRepn(pSigns, 9, i))
|
||||
if intSum ≥ 0 then set end of plstSums to intSum
|
||||
end repeat
|
||||
|
||||
set plstSumsSorted to sort(plstSums)
|
||||
set plstSumGroups to group(plstSumsSorted)
|
||||
|
||||
script groupLength
|
||||
on |λ|(a, b)
|
||||
set intA to length of a
|
||||
set intB to length of b
|
||||
if intA < intB then
|
||||
-1
|
||||
else if intA > intB then
|
||||
1
|
||||
else
|
||||
0
|
||||
end if
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
set lstMaxSum to maximumBy(groupLength, plstSumGroups)
|
||||
intercalate(linefeed, ¬
|
||||
{"Most common sum: " & item 1 of lstMaxSum, ¬
|
||||
"Number of instances: " & length of lstMaxSum})
|
||||
end mostCommonSum
|
||||
|
||||
|
||||
-- TEST ----------------------------------------------------------------------
|
||||
on run
|
||||
return sumsTo100()
|
||||
|
||||
-- Also returns a value, but slow:
|
||||
-- mostCommonSum()
|
||||
end run
|
||||
|
||||
|
||||
-- GENERIC FUNCTIONS ---------------------------------------------------------
|
||||
|
||||
-- nthPermutationWithRepn :: [a] -> Int -> Int -> [a]
|
||||
on nthPermutationWithRepn(xs, groupSize, iIndex)
|
||||
set intBase to length of xs
|
||||
set intSetSize to intBase ^ groupSize
|
||||
|
||||
if intBase < 1 or iIndex > intSetSize then
|
||||
{}
|
||||
else
|
||||
set baseElems to inBaseElements(xs, iIndex)
|
||||
set intZeros to groupSize - (length of baseElems)
|
||||
|
||||
if intZeros > 0 then
|
||||
replicate(intZeros, item 1 of xs) & baseElems
|
||||
else
|
||||
baseElems
|
||||
end if
|
||||
end if
|
||||
end nthPermutationWithRepn
|
||||
|
||||
-- inBaseElements :: [a] -> Int -> [String]
|
||||
on inBaseElements(xs, n)
|
||||
set intBase to length of xs
|
||||
|
||||
script nextDigit
|
||||
on |λ|(residue)
|
||||
set {divided, remainder} to quotRem(residue, intBase)
|
||||
|
||||
{valid:divided > 0, value:(item (remainder + 1) of xs), new:divided}
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
reverse of unfoldr(nextDigit, n)
|
||||
end inBaseElements
|
||||
|
||||
-- sort :: [a] -> [a]
|
||||
on sort(lst)
|
||||
((current application's NSArray's arrayWithArray:lst)'s ¬
|
||||
sortedArrayUsingSelector:"compare:") as list
|
||||
end sort
|
||||
|
||||
-- maximumBy :: (a -> a -> Ordering) -> [a] -> a
|
||||
on maximumBy(f, xs)
|
||||
set cmp to mReturn(f)
|
||||
script max
|
||||
on |λ|(a, b)
|
||||
if a is missing value or cmp's |λ|(a, b) < 0 then
|
||||
b
|
||||
else
|
||||
a
|
||||
end if
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
foldl(max, missing value, xs)
|
||||
end maximumBy
|
||||
|
||||
-- group :: Eq a => [a] -> [[a]]
|
||||
on group(xs)
|
||||
script eq
|
||||
on |λ|(a, b)
|
||||
a = b
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
groupBy(eq, xs)
|
||||
end group
|
||||
|
||||
-- groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
|
||||
on groupBy(f, xs)
|
||||
set mf to mReturn(f)
|
||||
|
||||
script enGroup
|
||||
on |λ|(a, x)
|
||||
if length of (active of a) > 0 then
|
||||
set h to item 1 of active of a
|
||||
else
|
||||
set h to missing value
|
||||
end if
|
||||
|
||||
if h is not missing value and mf's |λ|(h, x) then
|
||||
{active:(active of a) & x, sofar:sofar of a}
|
||||
else
|
||||
{active:{x}, sofar:(sofar of a) & {active of a}}
|
||||
end if
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
if length of xs > 0 then
|
||||
set dct to foldl(enGroup, {active:{item 1 of xs}, sofar:{}}, tail(xs))
|
||||
if length of (active of dct) > 0 then
|
||||
sofar of dct & {active of dct}
|
||||
else
|
||||
sofar of dct
|
||||
end if
|
||||
else
|
||||
{}
|
||||
end if
|
||||
end groupBy
|
||||
|
||||
-- tail :: [a] -> [a]
|
||||
on tail(xs)
|
||||
if length of xs > 1 then
|
||||
items 2 thru -1 of xs
|
||||
else
|
||||
{}
|
||||
end if
|
||||
end tail
|
||||
|
||||
|
||||
-- intercalate :: Text -> [Text] -> Text
|
||||
on intercalate(strText, lstText)
|
||||
set {dlm, my text item delimiters} to {my text item delimiters, strText}
|
||||
set strJoined to lstText as text
|
||||
set my text item delimiters to dlm
|
||||
return strJoined
|
||||
end intercalate
|
||||
|
||||
-- quotRem :: Integral a => a -> a -> (a, a)
|
||||
on quotRem(m, n)
|
||||
{m div n, m mod n}
|
||||
end quotRem
|
||||
|
||||
-- replicate :: Int -> a -> [a]
|
||||
on replicate(n, a)
|
||||
set out to {}
|
||||
if n < 1 then return out
|
||||
set dbl to {a}
|
||||
|
||||
repeat while (n > 1)
|
||||
if (n mod 2) > 0 then set out to out & dbl
|
||||
set n to (n div 2)
|
||||
set dbl to (dbl & dbl)
|
||||
end repeat
|
||||
return out & dbl
|
||||
end replicate
|
||||
|
||||
-- foldr :: (a -> b -> a) -> a -> [b] -> a
|
||||
on foldr(f, startValue, xs)
|
||||
tell mReturn(f)
|
||||
set v to startValue
|
||||
set lng to length of xs
|
||||
repeat with i from lng to 1 by -1
|
||||
set v to |λ|(v, item i of xs, i, xs)
|
||||
end repeat
|
||||
return v
|
||||
end tell
|
||||
end foldr
|
||||
|
||||
-- foldl :: (a -> b -> a) -> a -> [b] -> a
|
||||
on foldl(f, startValue, xs)
|
||||
tell mReturn(f)
|
||||
set v to startValue
|
||||
set lng to length of xs
|
||||
repeat with i from 1 to lng
|
||||
set v to |λ|(v, item i of xs, i, xs)
|
||||
end repeat
|
||||
return v
|
||||
end tell
|
||||
end foldl
|
||||
|
||||
-- unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
|
||||
on unfoldr(f, v)
|
||||
set mf to mReturn(f)
|
||||
set lst to {}
|
||||
set recM to mf's |λ|(v)
|
||||
repeat while (valid of recM) is true
|
||||
set end of lst to value of recM
|
||||
set recM to mf's |λ|(new of recM)
|
||||
end repeat
|
||||
lst & value of recM
|
||||
end unfoldr
|
||||
|
||||
-- until :: (a -> Bool) -> (a -> a) -> a -> a
|
||||
on |until|(p, f, x)
|
||||
set mp to mReturn(p)
|
||||
set v to x
|
||||
|
||||
tell mReturn(f)
|
||||
repeat until mp's |λ|(v)
|
||||
set v to |λ|(v)
|
||||
end repeat
|
||||
end tell
|
||||
return v
|
||||
end |until|
|
||||
|
||||
-- map :: (a -> b) -> [a] -> [b]
|
||||
on map(f, xs)
|
||||
tell mReturn(f)
|
||||
set lng to length of xs
|
||||
set lst to {}
|
||||
repeat with i from 1 to lng
|
||||
set end of lst to |λ|(item i of xs, i, xs)
|
||||
end repeat
|
||||
return lst
|
||||
end tell
|
||||
end map
|
||||
|
||||
|
||||
-- Lift 2nd class handler function into 1st class script wrapper
|
||||
-- mReturn :: Handler -> Script
|
||||
on mReturn(f)
|
||||
if class of f is script then
|
||||
f
|
||||
else
|
||||
script
|
||||
property |λ| : f
|
||||
end script
|
||||
end if
|
||||
end mReturn
|
||||
56
Task/Sum-to-100/AutoHotkey/sum-to-100.ahk
Normal file
56
Task/Sum-to-100/AutoHotkey/sum-to-100.ahk
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
output:=""
|
||||
for k, v in (sum2num(100))
|
||||
output .= k "`n"
|
||||
MsgBox, 262144, , % output
|
||||
|
||||
mx := []
|
||||
loop 123456789{
|
||||
x := sum2num(A_Index)
|
||||
mx[x.Count()] := mx[x.Count()] ? mx[x.Count()] ", " A_Index : A_Index
|
||||
}
|
||||
MsgBox, 262144, , % mx[mx.MaxIndex()] " has " mx.MaxIndex() " solutions"
|
||||
|
||||
loop {
|
||||
if !sum2num(A_Index).Count(){
|
||||
MsgBox, 262144, , % "Lowest positive sum that can't be expressed is " A_Index
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
sum2num(num){
|
||||
output := []
|
||||
loop % 6561
|
||||
{
|
||||
oper := SubStr("00000000" ConvertBase(10, 3, A_Index-1), -7)
|
||||
oper := StrReplace(oper, 0, "+")
|
||||
oper := StrReplace(oper, 1, "-")
|
||||
oper := StrReplace(oper, 2, ".")
|
||||
str := ""
|
||||
loop 9
|
||||
str .= A_Index . SubStr(oper, A_Index, 1)
|
||||
str := StrReplace(str, ".")
|
||||
loop 2
|
||||
{
|
||||
val := 0
|
||||
for i, v in StrSplit(str, "+")
|
||||
for j, m in StrSplit(v, "-")
|
||||
val += A_Index=1 ? m : 0-m
|
||||
if (val = num)
|
||||
output[str] := true
|
||||
str := "-" str
|
||||
}
|
||||
}
|
||||
Sort, output
|
||||
return output
|
||||
}
|
||||
|
||||
; https://www.autohotkey.com/boards/viewtopic.php?p=21143&sid=02b9c92ea98737f1db6067b80a2a59cd#p21143
|
||||
ConvertBase(InputBase, OutputBase, nptr){
|
||||
static u := A_IsUnicode ? "_wcstoui64" : "_strtoui64"
|
||||
static v := A_IsUnicode ? "_i64tow" : "_i64toa"
|
||||
VarSetCapacity(s, 66, 0)
|
||||
value := DllCall("msvcrt.dll\" u, "Str", nptr, "UInt", 0, "UInt", InputBase, "CDECL Int64")
|
||||
DllCall("msvcrt.dll\" v, "Int64", value, "Str", s, "UInt", OutputBase, "CDECL")
|
||||
return s
|
||||
}
|
||||
111
Task/Sum-to-100/C++/sum-to-100.cpp
Normal file
111
Task/Sum-to-100/C++/sum-to-100.cpp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* RossetaCode: Sum to 100, C++, STL, OOP.
|
||||
* Works with: MSC 16.0 (MSVS2010); GCC 5.1 (use -std=c++11 or -std=c++14 etc.).
|
||||
*
|
||||
* Find solutions to the "sum to one hundred" puzzle.
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Expression{
|
||||
private:
|
||||
enum { NUMBER_OF_DIGITS = 9 }; // hack for C++98, use const int in C++11
|
||||
enum Op { ADD, SUB, JOIN };
|
||||
int code[NUMBER_OF_DIGITS];
|
||||
public:
|
||||
static const int NUMBER_OF_EXPRESSIONS;
|
||||
Expression(){
|
||||
for ( int i = 0; i < NUMBER_OF_DIGITS; i++ )
|
||||
code[i] = ADD;
|
||||
}
|
||||
Expression& operator++(int){ // post incrementation
|
||||
for ( int i = 0; i < NUMBER_OF_DIGITS; i++ )
|
||||
if ( ++code[i] > JOIN ) code[i] = ADD;
|
||||
else break;
|
||||
return *this;
|
||||
}
|
||||
operator int() const{
|
||||
int value = 0, number = 0, sign = (+1);
|
||||
for ( int digit = 1; digit <= 9; digit++ )
|
||||
switch ( code[NUMBER_OF_DIGITS - digit] ){
|
||||
case ADD: value += sign*number; number = digit; sign = (+1); break;
|
||||
case SUB: value += sign*number; number = digit; sign = (-1); break;
|
||||
case JOIN: number = 10*number + digit; break;
|
||||
}
|
||||
return value + sign*number;
|
||||
}
|
||||
operator string() const{
|
||||
string s;
|
||||
for ( int digit = 1; digit <= NUMBER_OF_DIGITS; digit++ ){
|
||||
switch( code[NUMBER_OF_DIGITS - digit] ){
|
||||
case ADD: if ( digit > 1 ) s.push_back('+'); break;
|
||||
case SUB: s.push_back('-'); break;
|
||||
}
|
||||
s.push_back('0' + digit);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
};
|
||||
const int Expression::NUMBER_OF_EXPRESSIONS = 2 * 3*3*3*3 * 3*3*3*3;
|
||||
|
||||
ostream& operator<< (ostream& os, Expression& ex){
|
||||
ios::fmtflags oldFlags(os.flags());
|
||||
os << setw(9) << right << static_cast<int>(ex) << " = "
|
||||
<< setw(0) << left << static_cast<string>(ex) << endl;
|
||||
os.flags(oldFlags);
|
||||
return os;
|
||||
}
|
||||
|
||||
struct Stat{
|
||||
map<int,int> countSum;
|
||||
map<int, set<int> > sumCount;
|
||||
Stat(){
|
||||
Expression expression;
|
||||
for ( int i = 0; i < Expression::NUMBER_OF_EXPRESSIONS; i++, expression++ )
|
||||
countSum[expression]++;
|
||||
for ( auto it = countSum.begin(); it != countSum.end(); it++ )
|
||||
sumCount[it->second].insert(it->first);
|
||||
}
|
||||
};
|
||||
|
||||
void print(int givenSum){
|
||||
Expression expression;
|
||||
for ( int i = 0; i < Expression::NUMBER_OF_EXPRESSIONS; i++, expression++ )
|
||||
if ( expression == givenSum )
|
||||
cout << expression;
|
||||
}
|
||||
|
||||
void comment(string commentString){
|
||||
cout << endl << commentString << endl << endl;
|
||||
}
|
||||
|
||||
int main(){
|
||||
Stat stat;
|
||||
|
||||
comment( "Show all solutions that sum to 100" );
|
||||
const int givenSum = 100;
|
||||
print(givenSum);
|
||||
|
||||
comment( "Show the sum that has the maximum number of solutions" );
|
||||
auto maxi = max_element(stat.sumCount.begin(),stat.sumCount.end());
|
||||
auto it = maxi->second.begin();
|
||||
while ( *it < 0 ) it++;
|
||||
cout << static_cast<int>(*it) << " has " << maxi->first << " solutions" << endl;
|
||||
|
||||
comment( "Show the lowest positive number that can't be expressed" );
|
||||
int value = 0;
|
||||
while(stat.countSum.count(value) != 0) value++;
|
||||
cout << value << endl;
|
||||
|
||||
comment( "Show the ten highest numbers that can be expressed" );
|
||||
auto rit = stat.countSum.rbegin();
|
||||
for ( int i = 0; i < 10; i++, rit++ ) print(rit->first);
|
||||
|
||||
return 0;
|
||||
}
|
||||
127
Task/Sum-to-100/C-sharp/sum-to-100.cs
Normal file
127
Task/Sum-to-100/C-sharp/sum-to-100.cs
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// All unique expressions that have a plus sign in front of the 1; calculated in parallel
|
||||
var expressionsPlus = Enumerable.Range(0, (int)Math.Pow(3, 8)).AsParallel().Select(i => new Expression(i, 1));
|
||||
// All unique expressions that have a minus sign in front of the 1; calculated in parallel
|
||||
var expressionsMinus = Enumerable.Range(0, (int)Math.Pow(3, 8)).AsParallel().Select(i => new Expression(i, -1));
|
||||
var expressions = expressionsPlus.Concat(expressionsMinus);
|
||||
var results = new Dictionary<int, List<Expression>>();
|
||||
foreach (var e in expressions)
|
||||
{
|
||||
if (results.Keys.Contains(e.Value))
|
||||
results[e.Value].Add(e);
|
||||
else
|
||||
results[e.Value] = new List<Expression>() { e };
|
||||
}
|
||||
Console.WriteLine("Show all solutions that sum to 100");
|
||||
foreach (Expression e in results[100])
|
||||
Console.WriteLine(" " + e);
|
||||
Console.WriteLine("Show the sum that has the maximum number of solutions (from zero to infinity)");
|
||||
var summary = results.Keys.Select(k => new Tuple<int, int>(k, results[k].Count));
|
||||
var maxSols = summary.Aggregate((a, b) => a.Item2 > b.Item2 ? a : b);
|
||||
Console.WriteLine(" The sum " + maxSols.Item1 + " has " + maxSols.Item2 + " solutions.");
|
||||
Console.WriteLine("Show the lowest positive sum that can't be expressed (has no solutions), using the rules for this task");
|
||||
var lowestPositive = Enumerable.Range(1, int.MaxValue).First(x => !results.Keys.Contains(x));
|
||||
Console.WriteLine(" " + lowestPositive);
|
||||
Console.WriteLine("Show the ten highest numbers that can be expressed using the rules for this task (extra credit)");
|
||||
var highest = from k in results.Keys
|
||||
orderby k descending
|
||||
select k;
|
||||
foreach (var x in highest.Take(10))
|
||||
Console.WriteLine(" " + x);
|
||||
}
|
||||
}
|
||||
public enum Operations { Plus, Minus, Join };
|
||||
public class Expression
|
||||
{
|
||||
protected Operations[] Gaps;
|
||||
// 123456789 => there are 8 "gaps" between each number
|
||||
/// with 3 possibilities for each gap: plus, minus, or join
|
||||
public int Value; // What this expression sums up to
|
||||
protected int _one;
|
||||
|
||||
public Expression(int serial, int one)
|
||||
{
|
||||
_one = one;
|
||||
Gaps = new Operations[8];
|
||||
// This represents "serial" as a base 3 number, each Gap expression being a base-three digit
|
||||
int divisor = 2187; // == Math.Pow(3,7)
|
||||
int times;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
times = Math.DivRem(serial, divisor, out serial);
|
||||
divisor /= 3;
|
||||
if (times == 0)
|
||||
Gaps[i] = Operations.Join;
|
||||
else if (times == 1)
|
||||
Gaps[i] = Operations.Minus;
|
||||
else
|
||||
Gaps[i] = Operations.Plus;
|
||||
}
|
||||
// go ahead and calculate the value of this expression
|
||||
// because this is going to be done in a parallel thread (save time)
|
||||
Value = Evaluate();
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
string ret = _one.ToString();
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
switch (Gaps[i])
|
||||
{
|
||||
case Operations.Plus:
|
||||
ret += "+";
|
||||
break;
|
||||
case Operations.Minus:
|
||||
ret += "-";
|
||||
break;
|
||||
}
|
||||
ret += (i + 2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
private int Evaluate()
|
||||
/* Calculate what this expression equals */
|
||||
{
|
||||
var numbers = new int[9];
|
||||
int nc = 0;
|
||||
var operations = new List<Operations>();
|
||||
int a = 1;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (Gaps[i] == Operations.Join)
|
||||
a = a * 10 + (i + 2);
|
||||
else
|
||||
{
|
||||
if (a > 0)
|
||||
{
|
||||
if (nc == 0)
|
||||
a *= _one;
|
||||
numbers[nc++] = a;
|
||||
a = i + 2;
|
||||
}
|
||||
operations.Add(Gaps[i]);
|
||||
}
|
||||
}
|
||||
if (nc == 0)
|
||||
a *= _one;
|
||||
numbers[nc++] = a;
|
||||
int ni = 0;
|
||||
int left = numbers[ni++];
|
||||
foreach (var operation in operations)
|
||||
{
|
||||
int right = numbers[ni++];
|
||||
if (operation == Operations.Plus)
|
||||
left = left + right;
|
||||
else
|
||||
left = left - right;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
}
|
||||
136
Task/Sum-to-100/C/sum-to-100-1.c
Normal file
136
Task/Sum-to-100/C/sum-to-100-1.c
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* RossetaCode: Sum to 100, C99, an algorithm using ternary numbers.
|
||||
*
|
||||
* Find solutions to the "sum to one hundred" puzzle.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* There are only 13122 (i.e. 2*3**8) different possible expressions,
|
||||
* thus we can encode them as positive integer numbers from 0 to 13121.
|
||||
*/
|
||||
#define NUMBER_OF_EXPRESSIONS (2 * 3*3*3*3 * 3*3*3*3 )
|
||||
enum OP { ADD, SUB, JOIN };
|
||||
typedef int (*cmp)(const void*, const void*);
|
||||
|
||||
// Replacing struct Expression and struct CountSum by a tuple like
|
||||
// struct Pair { int first; int last; } is possible but would make the source
|
||||
// code less readable.
|
||||
|
||||
struct Expression{
|
||||
int sum;
|
||||
int code;
|
||||
}expressions[NUMBER_OF_EXPRESSIONS];
|
||||
int expressionsLength = 0;
|
||||
int compareExpressionBySum(const struct Expression* a, const struct Expression* b){
|
||||
return a->sum - b->sum;
|
||||
}
|
||||
|
||||
struct CountSum{
|
||||
int counts;
|
||||
int sum;
|
||||
}countSums[NUMBER_OF_EXPRESSIONS];
|
||||
int countSumsLength = 0;
|
||||
int compareCountSumsByCount(const struct CountSum* a, const struct CountSum* b){
|
||||
return a->counts - b->counts;
|
||||
}
|
||||
|
||||
int evaluate(int code){
|
||||
int value = 0, number = 0, power = 1;
|
||||
for ( int k = 9; k >= 1; k-- ){
|
||||
number = power*k + number;
|
||||
switch( code % 3 ){
|
||||
case ADD: value = value + number; number = 0; power = 1; break;
|
||||
case SUB: value = value - number; number = 0; power = 1; break;
|
||||
case JOIN: power = power * 10 ; break;
|
||||
}
|
||||
code /= 3;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void print(int code){
|
||||
static char s[19]; char* p = s;
|
||||
int a = 19683, b = 6561;
|
||||
for ( int k = 1; k <= 9; k++ ){
|
||||
switch((code % a) / b){
|
||||
case ADD: if ( k > 1 ) *p++ = '+'; break;
|
||||
case SUB: *p++ = '-'; break;
|
||||
}
|
||||
a = b;
|
||||
b = b / 3;
|
||||
*p++ = '0' + k;
|
||||
}
|
||||
*p = 0;
|
||||
printf("%9d = %s\n", evaluate(code), s);
|
||||
}
|
||||
|
||||
void comment(char* string){
|
||||
printf("\n\n%s\n\n", string);
|
||||
}
|
||||
|
||||
void init(void){
|
||||
for ( int i = 0; i < NUMBER_OF_EXPRESSIONS; i++ ){
|
||||
expressions[i].sum = evaluate(i);
|
||||
expressions[i].code = i;
|
||||
}
|
||||
expressionsLength = NUMBER_OF_EXPRESSIONS;
|
||||
qsort(expressions,expressionsLength,sizeof(struct Expression),(cmp)compareExpressionBySum);
|
||||
|
||||
int j = 0;
|
||||
countSums[0].counts = 1;
|
||||
countSums[0].sum = expressions[0].sum;
|
||||
for ( int i = 0; i < expressionsLength; i++ ){
|
||||
if ( countSums[j].sum != expressions[i].sum ){
|
||||
j++;
|
||||
countSums[j].counts = 1;
|
||||
countSums[j].sum = expressions[i].sum;
|
||||
}
|
||||
else
|
||||
countSums[j].counts++;
|
||||
}
|
||||
countSumsLength = j + 1;
|
||||
qsort(countSums,countSumsLength,sizeof(struct CountSum),(cmp)compareCountSumsByCount);
|
||||
}
|
||||
|
||||
int main(void){
|
||||
|
||||
init();
|
||||
|
||||
comment("Show all solutions that sum to 100");
|
||||
const int givenSum = 100;
|
||||
struct Expression ex = { givenSum, 0 };
|
||||
struct Expression* found;
|
||||
if ( found = bsearch(&ex,expressions,expressionsLength,
|
||||
sizeof(struct Expression),(cmp)compareExpressionBySum) ){
|
||||
while ( found != expressions && (found-1)->sum == givenSum )
|
||||
found--;
|
||||
while ( found != &expressions[expressionsLength] && found->sum == givenSum )
|
||||
print(found++->code);
|
||||
}
|
||||
|
||||
comment("Show the positve sum that has the maximum number of solutions");
|
||||
int maxSumIndex = countSumsLength - 1;
|
||||
while( countSums[maxSumIndex].sum < 0 )
|
||||
maxSumIndex--;
|
||||
printf("%d has %d solutions\n",
|
||||
countSums[maxSumIndex].sum, countSums[maxSumIndex].counts);
|
||||
|
||||
comment("Show the lowest positive number that can't be expressed");
|
||||
for ( int value = 0; ; value++ ){
|
||||
struct Expression ex = { value, 0 };
|
||||
if (!bsearch(&ex,expressions,expressionsLength,
|
||||
sizeof(struct Expression),(cmp)compareExpressionBySum)){
|
||||
printf("%d\n", value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
comment("Show the ten highest numbers that can be expressed");
|
||||
for ( int i = expressionsLength-1; i >= expressionsLength-10; i-- )
|
||||
print(expressions[i].code);
|
||||
|
||||
return 0;
|
||||
}
|
||||
86
Task/Sum-to-100/C/sum-to-100-2.c
Normal file
86
Task/Sum-to-100/C/sum-to-100-2.c
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* RossetaCode: Sum to 100, C11, MCU friendly.
|
||||
*
|
||||
* Find solutions to the "sum to one hundred" puzzle.
|
||||
*
|
||||
* We optimize algorithms for size. Therefore we don't use arrays, but recompute
|
||||
* all values again and again. It is a little surprise that the time efficiency
|
||||
* is quite acceptable.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
enum OP { ADD, SUB, JOIN };
|
||||
|
||||
int evaluate(int code){
|
||||
int value = 0, number = 0, power = 1;
|
||||
for ( int k = 9; k >= 1; k-- ){
|
||||
number = power*k + number;
|
||||
switch( code % 3 ){
|
||||
case ADD: value = value + number; number = 0; power = 1; break;
|
||||
case SUB: value = value - number; number = 0; power = 1; break;
|
||||
case JOIN: power = power * 10 ; break;
|
||||
}
|
||||
code /= 3;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void print(int code){
|
||||
static char s[19]; char* p = s;
|
||||
int a = 19683, b = 6561;
|
||||
for ( int k = 1; k <= 9; k++ ){
|
||||
switch((code % a) / b){
|
||||
case ADD: if ( k > 1 ) *p++ = '+'; break;
|
||||
case SUB: *p++ = '-'; break;
|
||||
}
|
||||
a = b;
|
||||
b = b / 3;
|
||||
*p++ = '0' + k;
|
||||
}
|
||||
*p = 0;
|
||||
printf("%9d = %s\n", evaluate(code), s);
|
||||
}
|
||||
|
||||
int main(void){
|
||||
|
||||
int i,j;
|
||||
const int nexpr = 13122;
|
||||
#define LOOP(K) for (K = 0; K < nexpr; K++)
|
||||
|
||||
puts("\nShow all solutions that sum to 100\n");
|
||||
LOOP(i) if ( evaluate(i) == 100 ) print(i);
|
||||
|
||||
puts("\nShow the sum that has the maximum number of solutions\n");
|
||||
int best, nbest = (-1);
|
||||
LOOP(i){
|
||||
int test = evaluate(i);
|
||||
if ( test > 0 ){
|
||||
int ntest = 0;
|
||||
LOOP(j) if ( evaluate(j) == test ) ntest++;
|
||||
if ( ntest > nbest ){ best = test; nbest = ntest; }
|
||||
}
|
||||
}
|
||||
printf("%d has %d solutions\n", best,nbest);
|
||||
|
||||
puts("\nShow the lowest positive number that can't be expressed\n");
|
||||
for ( i = 0; i <= 123456789; i++ ){
|
||||
LOOP(j) if ( i == evaluate(j) ) break;
|
||||
if ( i != evaluate(j) ) break;
|
||||
}
|
||||
printf("%d\n",i);
|
||||
|
||||
puts("\nShow the ten highest numbers that can be expressed\n");
|
||||
int limit = 123456789 + 1;
|
||||
for ( i = 1; i <= 10; i++ ) {
|
||||
int best = 0;
|
||||
LOOP(j){
|
||||
int test = evaluate(j);
|
||||
if ( test < limit && test > best ) best = test;
|
||||
}
|
||||
LOOP(j) if ( evaluate(j) == best ) print(j);
|
||||
limit = best;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
20
Task/Sum-to-100/Common-Lisp/sum-to-100.lisp
Normal file
20
Task/Sum-to-100/Common-Lisp/sum-to-100.lisp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
(defun f (lst &optional (sum 100) (so-far nil))
|
||||
"Takes a list of digits as argument"
|
||||
(if (null lst)
|
||||
(cond ((= sum 0) (format t "~d = ~{~@d~}~%" (apply #'+ so-far) (reverse so-far)) 1)
|
||||
(t 0) )
|
||||
(let ((total 0)
|
||||
(len (length lst)) )
|
||||
(dotimes (i len total)
|
||||
(let* ((str1 (butlast lst i))
|
||||
(num1 (or (numlist-to-string str1) 0))
|
||||
(rem (nthcdr (- len i) lst)) )
|
||||
(incf total
|
||||
(+ (f rem (- sum num1) (cons num1 so-far))
|
||||
(f rem (+ sum num1) (cons (- num1) so-far)) )))))))
|
||||
|
||||
|
||||
(defun numlist-to-string (lst)
|
||||
"Convert a list of digits into an integer"
|
||||
(when lst
|
||||
(parse-integer (format nil "~{~d~}" lst)) ))
|
||||
153
Task/Sum-to-100/D/sum-to-100.d
Normal file
153
Task/Sum-to-100/D/sum-to-100.d
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
import std.stdio;
|
||||
|
||||
void main() {
|
||||
import std.algorithm : each, max, reduce, sort;
|
||||
import std.range : take;
|
||||
|
||||
Stat stat = new Stat();
|
||||
|
||||
comment("Show all solutions that sum to 100");
|
||||
immutable givenSum = 100;
|
||||
print(givenSum);
|
||||
|
||||
comment("Show the sum that has the maximum number of solutions");
|
||||
const int maxCount = reduce!max(stat.sumCount.keys);
|
||||
int maxSum;
|
||||
foreach(key, entry; stat.sumCount[maxCount]) {
|
||||
if (key >= 0) {
|
||||
maxSum = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
writeln(maxSum, " has ", maxCount, " solutions");
|
||||
|
||||
comment("Show the lowest positive number that can't be expressed");
|
||||
int value = 0;
|
||||
while (value in stat.countSum) {
|
||||
value++;
|
||||
}
|
||||
writeln(value);
|
||||
|
||||
comment("Show the ten highest numbers that can be expressed");
|
||||
const int n = stat.countSum.keys.length;
|
||||
auto sums = stat.countSum.keys;
|
||||
sums.sort!"a>b"
|
||||
.take(10)
|
||||
.each!print;
|
||||
}
|
||||
|
||||
void comment(string commentString) {
|
||||
writeln();
|
||||
writeln(commentString);
|
||||
writeln();
|
||||
}
|
||||
|
||||
void print(int givenSum) {
|
||||
Expression expression = new Expression();
|
||||
for (int i=0; i<Expression.NUMBER_OF_EXPRESSIONS; i++, expression.next()) {
|
||||
if (expression.toInt() == givenSum) {
|
||||
expression.print();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Expression {
|
||||
private enum NUMBER_OF_DIGITS = 9;
|
||||
private enum ADD = 0;
|
||||
private enum SUB = 1;
|
||||
private enum JOIN = 2;
|
||||
|
||||
enum NUMBER_OF_EXPRESSIONS = 2 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3;
|
||||
byte[NUMBER_OF_DIGITS] code;
|
||||
|
||||
Expression next() {
|
||||
for (int i=0; i<NUMBER_OF_DIGITS; i++) {
|
||||
if (++code[i] > JOIN) {
|
||||
code[i] = ADD;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
int toInt() {
|
||||
int value = 0;
|
||||
int number = 0;
|
||||
int sign = (+1);
|
||||
for (int digit=1; digit<=9; digit++) {
|
||||
switch (code[NUMBER_OF_DIGITS - digit]) {
|
||||
case ADD:
|
||||
value += sign * number;
|
||||
number = digit;
|
||||
sign = (+1);
|
||||
break;
|
||||
case SUB:
|
||||
value += sign * number;
|
||||
number = digit;
|
||||
sign = (-1);
|
||||
break;
|
||||
case JOIN:
|
||||
number = 10 * number + digit;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
return value + sign * number;
|
||||
}
|
||||
|
||||
void toString(scope void delegate(const(char)[]) sink) const {
|
||||
import std.conv : to;
|
||||
import std.format : FormatSpec, formatValue;
|
||||
import std.range : put;
|
||||
|
||||
auto fmt = FormatSpec!char("s");
|
||||
for (int digit=1; digit<=NUMBER_OF_DIGITS; digit++) {
|
||||
switch (code[NUMBER_OF_DIGITS - digit]) {
|
||||
case ADD:
|
||||
if (digit > 1) {
|
||||
put(sink, '+');
|
||||
}
|
||||
break;
|
||||
case SUB:
|
||||
put(sink, '-');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
formatValue(sink, digit, fmt);
|
||||
}
|
||||
}
|
||||
|
||||
void print() {
|
||||
print(stdout);
|
||||
}
|
||||
|
||||
void print(File printStream) {
|
||||
printStream.writefln("%9d = %s", toInt(), this);
|
||||
}
|
||||
}
|
||||
|
||||
class Stat {
|
||||
int[int] countSum;
|
||||
bool[int][int] sumCount;
|
||||
|
||||
this() {
|
||||
Expression expression = new Expression();
|
||||
for (int i=0; i<Expression.NUMBER_OF_EXPRESSIONS; i++, expression.next()) {
|
||||
int sum = expression.toInt();
|
||||
countSum[sum]++;
|
||||
}
|
||||
foreach (key, entry; countSum) {
|
||||
bool[int] set;
|
||||
if (entry in sumCount) {
|
||||
set = sumCount[entry];
|
||||
} else {
|
||||
set.clear();
|
||||
}
|
||||
set[key] = true;
|
||||
sumCount[entry] = set;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
Task/Sum-to-100/Elixir/sum-to-100.elixir
Normal file
46
Task/Sum-to-100/Elixir/sum-to-100.elixir
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
defmodule Sum do
|
||||
def to(val) do
|
||||
generate
|
||||
|> Enum.map(&{eval(&1), &1})
|
||||
|> Enum.filter(fn {v, _s} -> v==val end)
|
||||
|> Enum.each(&IO.inspect &1)
|
||||
end
|
||||
|
||||
def max_solve do
|
||||
generate
|
||||
|> Enum.group_by(&eval &1)
|
||||
|> Enum.filter_map(fn {k,_} -> k>=0 end, fn {k,v} -> {length(v),k} end)
|
||||
|> Enum.max
|
||||
|> fn {len,sum} -> IO.puts "sum of #{sum} has the maximum number of solutions : #{len}" end.()
|
||||
end
|
||||
|
||||
def min_solve do
|
||||
solve = generate |> Enum.group_by(&eval &1)
|
||||
Stream.iterate(1, &(&1+1))
|
||||
|> Enum.find(fn n -> solve[n]==nil end)
|
||||
|> fn sum -> IO.puts "lowest positive sum that can't be expressed : #{sum}" end.()
|
||||
end
|
||||
|
||||
def highest_sums(n\\10) do
|
||||
IO.puts "highest sums :"
|
||||
generate
|
||||
|> Enum.map(&eval &1)
|
||||
|> Enum.uniq
|
||||
|> Enum.sort_by(fn sum -> -sum end)
|
||||
|> Enum.take(n)
|
||||
|> IO.inspect
|
||||
end
|
||||
|
||||
defp generate do
|
||||
x = ["+", "-", ""]
|
||||
for a <- ["-", ""], b <- x, c <- x, d <- x, e <- x, f <- x, g <- x, h <- x, i <- x,
|
||||
do: "#{a}1#{b}2#{c}3#{d}4#{e}5#{f}6#{g}7#{h}8#{i}9"
|
||||
end
|
||||
|
||||
defp eval(str), do: Code.eval_string(str) |> elem(0)
|
||||
end
|
||||
|
||||
Sum.to(100)
|
||||
Sum.max_solve
|
||||
Sum.min_solve
|
||||
Sum.highest_sums
|
||||
18
Task/Sum-to-100/F-Sharp/sum-to-100-1.fs
Normal file
18
Task/Sum-to-100/F-Sharp/sum-to-100-1.fs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
(*
|
||||
Generate the data set
|
||||
Nigel Galloway February 22nd., 2017
|
||||
*)
|
||||
type N = {n:string; g:int}
|
||||
let N = seq {
|
||||
let rec fn n i g e l = seq {
|
||||
match i with
|
||||
|9 -> yield {n=l + "-9"; g=g+e-9}
|
||||
yield {n=l + "+9"; g=g+e+9}
|
||||
yield {n=l + "9"; g=g+e*10+9*n}
|
||||
|_ -> yield! fn -1 (i+1) (g+e) -i (l + string -i)
|
||||
yield! fn 1 (i+1) (g+e) i (l + "+" + string i)
|
||||
yield! fn n (i+1) g (e*10+i*n) (l + string i)
|
||||
}
|
||||
yield! fn 1 2 0 1 "1"
|
||||
yield! fn -1 2 0 -1 "-1"
|
||||
}
|
||||
1
Task/Sum-to-100/F-Sharp/sum-to-100-2.fs
Normal file
1
Task/Sum-to-100/F-Sharp/sum-to-100-2.fs
Normal file
|
|
@ -0,0 +1 @@
|
|||
N |> Seq.filter(fun n->n.g=100) |> Seq.iter(fun n->printfn "%s" n.n)
|
||||
2
Task/Sum-to-100/F-Sharp/sum-to-100-3.fs
Normal file
2
Task/Sum-to-100/F-Sharp/sum-to-100-3.fs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
let n,g = N |> Seq.filter(fun n->n.g>=0) |> Seq.countBy(fun n->n.g) |> Seq.maxBy(snd)
|
||||
printfn "%d has %d solutions" n g
|
||||
3
Task/Sum-to-100/F-Sharp/sum-to-100-4.fs
Normal file
3
Task/Sum-to-100/F-Sharp/sum-to-100-4.fs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
match N |> Seq.filter(fun n->n.g>=0) |> Seq.distinctBy(fun n->n.g) |> Seq.sortBy(fun n->n.g) |> Seq.pairwise |> Seq.tryFind(fun n->(snd n).g-(fst n).g > 1) with
|
||||
|Some(n) -> printfn "least non-value is %d" ((fst n).g+1)
|
||||
|None -> printfn "No non-values found"
|
||||
1
Task/Sum-to-100/F-Sharp/sum-to-100-5.fs
Normal file
1
Task/Sum-to-100/F-Sharp/sum-to-100-5.fs
Normal file
|
|
@ -0,0 +1 @@
|
|||
N |> Seq.filter(fun n->n.g>=0) |> Seq.distinctBy(fun n->n.g) |> Seq.sortBy(fun n->(-n.g)) |> Seq.take 10 |> Seq.iter(fun n->printfn "%d" n.g )
|
||||
52
Task/Sum-to-100/Forth/sum-to-100.fth
Normal file
52
Task/Sum-to-100/Forth/sum-to-100.fth
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
CREATE *OPS CHAR + C, CHAR - C, CHAR # C,
|
||||
CREATE 0OPS CHAR - C, CHAR # C,
|
||||
CREATE BUFF 43 C, 43 CHARS ALLOT
|
||||
CREATE PTR CELL ALLOT
|
||||
CREATE LIMITS 2 C, 3 C, 3 C, 3 C, 3 C, 3 C, 3 C, 3 C, 3 C,
|
||||
CREATE INDX 0 C, 0 C, 0 C, 0 C, 0 C, 0 C, 0 C, 0 C, 0 C,
|
||||
CREATE OPS 0OPS , *OPS , *OPS , *OPS , *OPS , *OPS , *OPS , *OPS , *OPS ,
|
||||
: B0 BUFF 1+ dup PTR ! 43 blank ;
|
||||
: B, ( c --) PTR @ C! 1 PTR +! ;
|
||||
CREATE STATS 123456790 ALLOT STATS 123456790 ERASE
|
||||
|
||||
: inc ( c-addr c-lim u -- t|f)
|
||||
1- tuck + >r swap dup rot + ( addr a-addr) ( R: l-addr)
|
||||
BEGIN dup C@ 1+ dup r@ C@ =
|
||||
IF drop 2dup =
|
||||
IF 2drop FALSE rdrop EXIT \ no inc, contents invalid
|
||||
ELSE 0 over C! 1- r> 1- >r \ reset and carry
|
||||
THEN
|
||||
ELSE swap C! drop TRUE rdrop EXIT
|
||||
THEN
|
||||
AGAIN ;
|
||||
: INDX+ INDX LIMITS 9 inc 0= ;
|
||||
: SYNTH B0 [CHAR] 0 B, 9 0 DO
|
||||
INDX I + C@ OPS I CELLS + @ + C@
|
||||
dup [CHAR] # <> IF BL B, B, BL B, ELSE drop THEN
|
||||
I [CHAR] 1 + B,
|
||||
LOOP BUFF COUNT ;
|
||||
: .MOST cr ." Sum that has the maximum number of solutions" cr 4 spaces
|
||||
STATS 0 STATS 1+ 123456789 bounds DO
|
||||
dup I c@ < IF drop drop I I c@ THEN
|
||||
LOOP swap STATS - . ." has " . ." solutions" ;
|
||||
: .CANT cr ." Lowest positive sum that can't be expressed" cr 4 spaces
|
||||
STATS 1+ ( 0 not positive) BEGIN dup c@ WHILE 1+ REPEAT STATS - . ;
|
||||
: .BEST cr ." Ten highest numbers that can be expressed" cr 4 spaces
|
||||
0 >r [ STATS 123456789 + ]L
|
||||
BEGIN r@ 10 < over STATS >= and
|
||||
WHILE dup c@ IF dup STATS - . r> 1+ >r THEN 1-
|
||||
REPEAT r> drop ;
|
||||
: . 0 <# #S #> TYPE ;
|
||||
: .INFX cr 4 spaces 9 0 DO
|
||||
INDX I + C@ OPS I cells + @ + C@
|
||||
dup [char] # <> IF emit ELSE drop THEN I 1+ .
|
||||
LOOP ;
|
||||
: REPORT ( n) dup 100 = IF .INFX THEN
|
||||
dup 0> IF STATS + dup c@ 1+ swap c! ELSE drop THEN ;
|
||||
: >NUM 0. bl word count >number 2drop d>s ;
|
||||
: # 10 * + ; \ numeric concatenation
|
||||
: + >NUM + ; \ infix +
|
||||
: - >NUM - ; \ infix -
|
||||
: .SOLUTIONS cr ." Solutions that sum to 100:"
|
||||
BEGIN SYNTH EVALUATE REPORT INDX+ UNTIL ;
|
||||
: SUM100 .SOLUTIONS .MOST .CANT .BEST cr ;
|
||||
131
Task/Sum-to-100/Fortran/sum-to-100-1.f
Normal file
131
Task/Sum-to-100/Fortran/sum-to-100-1.f
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
! RossetaCode: Sum to 100, Fortran 95, an algorithm using ternary numbers.
|
||||
!
|
||||
! Find solutions to the 'sum to one hundred' puzzle.
|
||||
!
|
||||
! We optimize algorithms for size. Therefore we don't use arrays, but recompute
|
||||
! all values again and again. It is a little surprise that the time efficiency
|
||||
! is quite acceptable. Actually the code is more compact than the implementation
|
||||
! in C++ (STL maps and sets). We purposely break DRY and use magic values.
|
||||
! Nevertheless, it is Fortran 95, free form lines, do-endo etc.
|
||||
|
||||
program sumto100
|
||||
|
||||
parameter (nexpr = 13122)
|
||||
|
||||
print *
|
||||
print *, 'Show all solutions that sum to 100'
|
||||
print *
|
||||
do i = 0, nexpr-1
|
||||
if ( ievaluate(i) .eq. 100 ) then
|
||||
call printexpr(i)
|
||||
endif
|
||||
enddo
|
||||
|
||||
print *
|
||||
print *, 'Show the sum that has the maximum number of solutions'
|
||||
print *
|
||||
ibest = -1
|
||||
nbest = -1
|
||||
do i = 0, nexpr-1
|
||||
itest = ievaluate(i)
|
||||
if ( itest .ge. 0 ) then
|
||||
ntest = 0
|
||||
do j = 0, nexpr-1
|
||||
if ( ievaluate(j) .eq. itest ) then
|
||||
ntest = ntest + 1
|
||||
endif
|
||||
enddo
|
||||
if ( (ntest .gt. nbest) ) then
|
||||
ibest = itest
|
||||
nbest = ntest
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
print *, ibest, ' has ', nbest, ' solutions'
|
||||
print *
|
||||
! do i = 0, nexpr-1
|
||||
! if ( ievaluate(i) .eq. ibest ) then
|
||||
! call printexpr(i)
|
||||
! endif
|
||||
! enddo
|
||||
|
||||
print *
|
||||
print *, 'Show the lowest positive number that can''t be expressed'
|
||||
print *
|
||||
loop: do i = 0,123456789
|
||||
do j = 0,nexpr-1
|
||||
if ( i .eq. ievaluate(j) ) then
|
||||
cycle loop
|
||||
endif
|
||||
enddo
|
||||
exit
|
||||
enddo loop
|
||||
print *, i
|
||||
|
||||
print *
|
||||
print *, 'Show the ten highest numbers that can be expressed'
|
||||
print *
|
||||
ilimit = 123456789
|
||||
do i = 1,10
|
||||
ibest = 0
|
||||
do j = 0, nexpr-1
|
||||
itest = ievaluate(j)
|
||||
if ( (itest .le. ilimit) .and. (itest .gt. ibest ) ) then
|
||||
ibest = itest
|
||||
endif
|
||||
enddo
|
||||
do j = 0, nexpr-1
|
||||
if ( ievaluate(j) .eq. ibest ) then
|
||||
call printexpr(j)
|
||||
endif
|
||||
enddo
|
||||
ilimit = ibest - 1;
|
||||
enddo
|
||||
|
||||
end
|
||||
|
||||
function ievaluate(icode)
|
||||
ic = icode
|
||||
ievaluate = 0
|
||||
n = 0
|
||||
ip = 1
|
||||
do k = 9,1,-1
|
||||
n = ip*k + n
|
||||
select case(mod(ic,3))
|
||||
case ( 0 )
|
||||
ievaluate = ievaluate + n
|
||||
n = 0
|
||||
ip = 1
|
||||
case ( 1 )
|
||||
ievaluate = ievaluate - n
|
||||
n = 0
|
||||
ip = 1
|
||||
case ( 2 )
|
||||
ip = ip * 10
|
||||
end select
|
||||
ic = ic / 3
|
||||
enddo
|
||||
end
|
||||
|
||||
subroutine printexpr(icode)
|
||||
character(len=32) s
|
||||
ia = 19683
|
||||
ib = 6561
|
||||
s = ""
|
||||
do k = 1,9
|
||||
ic = mod(icode,ia) / ib
|
||||
ia = ib
|
||||
ib = ib / 3
|
||||
select case(mod(ic,3))
|
||||
case ( 0 )
|
||||
if ( k .gt. 1 ) then
|
||||
s = trim(s) // '+'
|
||||
endif
|
||||
case ( 1 )
|
||||
s = trim(s) // '-'
|
||||
end select
|
||||
s = trim(s) // char(ichar('0')+k)
|
||||
end do
|
||||
ivalue = ievaluate(icode)
|
||||
print *, ivalue, ' = ', s
|
||||
end
|
||||
107
Task/Sum-to-100/Fortran/sum-to-100-2.f
Normal file
107
Task/Sum-to-100/Fortran/sum-to-100-2.f
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
INTEGER NDIGITS,TARGET !Document the shape.
|
||||
PARAMETER (NDIGITS = 9, TARGET = 100)
|
||||
INTEGER*1 OP(NDIGITS) !A set of operation codes, associated with each digit.
|
||||
INTEGER N,D,P !Number, digit, power.
|
||||
CHARACTER*1 OPNAME(-1:+1) !Encodement of the operations.
|
||||
PARAMETER (OPNAME = (/"-"," ","+"/)) !These will look nice.
|
||||
CHARACTER*20 TEXT !A scratchpad for the expression. Single digits only.
|
||||
INTEGER I,L,H,ME !Assistants.
|
||||
LOGICAL CURSE !Needed for a Comb Sort.
|
||||
INTEGER LOOP,NHIT !Some counters.
|
||||
INTEGER ENUFF !Collect the results.
|
||||
PARAMETER (ENUFF = 20000) !Surely big enough...
|
||||
INTEGER VALUE(ENUFF) !A table.
|
||||
INTEGER V,VV,PV,VE !For scanning the table.
|
||||
INTEGER MSG !I/O unit number.
|
||||
|
||||
MSG = 6 !Standard output.
|
||||
WRITE(MSG,1) NDIGITS,TARGET !Announce.
|
||||
1 FORMAT ("To find expressions of ",I0," digits in order, "
|
||||
1 "interspersed with + or -, adding to ",I0,/)
|
||||
NHIT = 0 !No matches to TARGET.
|
||||
LOOP = 0 !Because none have been made.
|
||||
OP = -1 !Start the expression sequence.
|
||||
|
||||
Calculate the value of the expression given by OP(i) i pairs.
|
||||
100 LOOP = LOOP + 1 !Here we go again.
|
||||
N = 0 !Clear the number.
|
||||
D = 0 !No previous digits have been seen.
|
||||
P = 1 !The power for the first digit.
|
||||
DO I = NDIGITS,1,-1 !Going backwards sees the digits before the sign.
|
||||
D = D + I*P !Assimilate the digit string backwards.
|
||||
IF (OP(I).EQ.0) THEN !A no-operation?
|
||||
P = P*10 !Yes. Prepare the power for the next digit leftwards.
|
||||
ELSE !Otherwise, add or subtract the digit string's value.
|
||||
N = N + SIGN(D,OP(I)) !By transferring the sign to D..
|
||||
D = 0 !Clear, ready for the next digit string.
|
||||
P = 1 !The starting power, again.
|
||||
END IF !So much for that step.
|
||||
END DO !On to the next.
|
||||
IF (OP(1).EQ.0) N = N + D !Provide an implicit add for an unsigned start.
|
||||
VALUE(LOOP) = N !Save the value for later...
|
||||
IF (N.EQ.TARGET) THEN !Well then?
|
||||
NHIT = NHIT + 1 !Yay!
|
||||
WRITE (TEXT,101) (OPNAME(OP(I)),I, I = 1,NDIGITS) !Translate the expression.
|
||||
101 FORMAT (10(A1,I1)) !Single-character operation codes, single-digit number parts.
|
||||
CALL DEBLANK(TEXT,L) !Squeeze out the no-operations, so numbers are together.
|
||||
WRITE (MSG,102) N,TEXT(1:L) !Result!
|
||||
102 FORMAT (I5,": ",A) !This should do.
|
||||
END IF !So much for that.
|
||||
|
||||
Concoct the next expression, working as if with a bignumber in base three, though offset.
|
||||
200 P = NDIGITS !Start with the low-order digit.
|
||||
201 OP(P) = OP(P) + 1 !Add one to it.
|
||||
IF (OP(P).GT.1) THEN !Is a carry needed?
|
||||
OP(P) = -1 !Yes. Set the digit back to the start.
|
||||
P = P - 1 !Go up a power.
|
||||
IF (P.GT.0) GO TO 201 !And augment the next digit up.
|
||||
END IF !Once the carry fizzles, the increment is complete.
|
||||
IF (OP(1).LE.0) GO TO 100 !A leading + is equivalent to a leading no-op.
|
||||
|
||||
Contemplate the collection.
|
||||
300 WRITE (6,301) LOOP,NHIT
|
||||
301 FORMAT (/,I0," evaluations, ",I0," hit the target.")
|
||||
Crank up a comb sort.
|
||||
H = LOOP - 1 !Last - First, and not +1.
|
||||
IF (H.LE.0) STOP "Huh?" !Ha ha.
|
||||
310 H = MAX(1,H*10/13) !The special feature.
|
||||
IF (H.EQ.9 .OR. H.EQ.10) H = 11 !A twiddle.
|
||||
CURSE = .FALSE. !So far, so good.
|
||||
DO I = LOOP - H,1,-1 !If H = 1, this is a BubbleSort.
|
||||
IF (VALUE(I) .GT. VALUE(I + H)) THEN !One compare.
|
||||
N = VALUE(I);VALUE(I)=VALUE(I+H);VALUE(I+H)=N !One swap.
|
||||
CURSE = .TRUE. !One curse.
|
||||
END IF !One test.
|
||||
END DO !One loop.
|
||||
IF (CURSE .OR. H.GT.1) GO TO 310 !Work remains?
|
||||
Chase after some results.
|
||||
H = 0 !Hunt the first omitted positive number.
|
||||
VE = 0 !No equal values have been seen.
|
||||
ME = 0 !So, their maximum run length is short.
|
||||
PV = VALUE(1) !Grab the first value,
|
||||
DO I = 2,LOOP !And scan the successors.
|
||||
V = VALUE(I) !The value of the moment.
|
||||
IF (V.LE.0) CYCLE !Only positive numbers are of interest.
|
||||
IF (V.GT.PV + 1) THEN !Is there a gap?
|
||||
IF (H.LE.0) H = PV + 1 !Recall the first such.
|
||||
END IF !Perhaps a list of the first dew?
|
||||
IF (V.EQ.PV) THEN !Is it the same as the one before?
|
||||
VE = VE + 1 !Yes. Count up the length of the run.
|
||||
IF (VE.GT.ME) THEN !Is this a longer run?
|
||||
ME = VE !Yes. Remember its length.
|
||||
VV = V !And its value.
|
||||
END IF !So much for runs of equal values.
|
||||
ELSE !But if it is not the same,
|
||||
VE = 0 !A fresh count awaits.
|
||||
END IF !So much for comparing one value to its predecessor.
|
||||
PV = V !Be ready for the next time around.
|
||||
END DO !On to the next.
|
||||
|
||||
Cast forth the results.
|
||||
IF (ME.GT.1) WRITE (MSG,320) VV,ME + 1 !Counting started with the second occurrence.
|
||||
320 FORMAT (I0," has the maximum number of attainments:",I0)
|
||||
IF (H.GT.0) WRITE (MSG,321) H !Surely there will be one.
|
||||
321 FORMAT ("The lowest positive sum that can't be expressed is ",I0)
|
||||
WRITE (MSG,322) VALUE(LOOP - 9:LOOP) !Surely LOOP > 9.
|
||||
322 FORMAT ("The ten highest sums: ",10(I0:","))
|
||||
END !That was fun!
|
||||
91
Task/Sum-to-100/FreeBASIC/sum-to-100.basic
Normal file
91
Task/Sum-to-100/FreeBASIC/sum-to-100.basic
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#define PERM 13122
|
||||
|
||||
'Between any two adjacent digits there can be nothing, a plus, or a minus.
|
||||
'And the first term can only be + or -
|
||||
'This is equivalent to an eight-digit base 3 number. We therefore only need
|
||||
'to consider 2*3^8=13122 possibilities
|
||||
|
||||
function ndig(n as uinteger) as uinteger
|
||||
return 1+int(log(n+0.5)/log(10))
|
||||
end function
|
||||
|
||||
function calculate( byval n as uinteger, outstr as string ) as integer
|
||||
'calculates the sum given by one of the 13122 possibilities, as well as
|
||||
'storing the equation itself as a string
|
||||
outstr = "9"
|
||||
dim as integer ret = 0, curr = 9
|
||||
dim as boolean firstplus = n>=PERM/2
|
||||
for i as integer = 8 to 1 step -1
|
||||
select case n mod 3
|
||||
case 0 'no symbol means we just prepend the next number
|
||||
curr += i*10^(ndig(curr))
|
||||
case 1 'addition: add the current term to the running sum, and clear the current term
|
||||
ret += curr
|
||||
curr = i
|
||||
outstr = " + " + outstr
|
||||
case 2 'subtraction: minus the current term from the running sum, and clear the current term
|
||||
ret -= curr
|
||||
curr = i
|
||||
outstr = " - " + outstr
|
||||
end select
|
||||
outstr = str(i) + outstr 'prepend the previous digit to the string
|
||||
n \= 3 'get next symbol
|
||||
next i
|
||||
if firstplus = 0 then
|
||||
outstr = "-"+outstr
|
||||
ret -= curr
|
||||
else
|
||||
ret += curr
|
||||
end if
|
||||
outstr = outstr + " = " + str(ret)
|
||||
return ret
|
||||
end function
|
||||
|
||||
'calculate and store all 13122 solutions
|
||||
dim as string eqn
|
||||
dim as integer n, sum(0 to PERM-1), curr
|
||||
for n = 0 to PERM-1
|
||||
curr = calculate(n, eqn)
|
||||
sum(n) = curr
|
||||
if curr = 100 then print eqn
|
||||
next n
|
||||
|
||||
'what is the sum that has the most solutions?
|
||||
dim as integer champ = 0, cnum = 0, i, j, acc
|
||||
for i = 0 to PERM-1
|
||||
acc = 0
|
||||
for j = i to PERM-1
|
||||
if sum(j) = sum(i) then acc+=1
|
||||
next j
|
||||
if acc>cnum then
|
||||
champ = sum(i)
|
||||
cnum=acc
|
||||
end if
|
||||
next i
|
||||
print "The sum with the most occurrences is ";champ;", which shows up ";cnum;" times."
|
||||
|
||||
'what is the first nonnegative number that has no solution
|
||||
for i = 0 to 123456788
|
||||
for j = 0 to PERM-1
|
||||
if sum(j)=i then goto nexti
|
||||
next j
|
||||
print "The first number that has no solution is ";i
|
||||
exit for
|
||||
nexti:
|
||||
next i
|
||||
|
||||
'What are the ten highest numbers?
|
||||
'this partially destroys the information in the array, but who cares?
|
||||
'We're almost done and these excessive questionnaires are the worst
|
||||
'and most boring part of Rosetta Code tasks
|
||||
|
||||
print "The ten highest numbers attainable are:"
|
||||
champ = 0
|
||||
for i = 1 to 10
|
||||
for j = 0 to PERM-1
|
||||
if sum(j)>sum(champ) then champ = j
|
||||
next j
|
||||
calculate(champ, eqn)
|
||||
print eqn
|
||||
sum(champ) = -9999 'overwrite to stop this being found a second time
|
||||
next i
|
||||
48
Task/Sum-to-100/Frink/sum-to-100.frink
Normal file
48
Task/Sum-to-100/Frink/sum-to-100.frink
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
digits = array[1 to 9]
|
||||
opList = makeArray[[8], ["", " + ", " - "]]
|
||||
opList.pushFirst[["", "-"]]
|
||||
countDict = new dict
|
||||
|
||||
multifor ops = opList
|
||||
{
|
||||
str = ""
|
||||
for d = rangeOf[digits]
|
||||
str = str + ops@d + digits@d
|
||||
e = eval[str]
|
||||
countDict.increment[e, 1]
|
||||
if e == 100
|
||||
println[str]
|
||||
}
|
||||
println[]
|
||||
|
||||
// Find the sum that has the maximum number of solutions
|
||||
freq = toArray[countDict]
|
||||
sort[freq, {|a,b| -(a@1 <=> b@1)}]
|
||||
max = freq@0@1
|
||||
print["Maximum count is $max at: "]
|
||||
n = 0
|
||||
while freq@n@1 == max
|
||||
{
|
||||
print[freq@n@0 + " "]
|
||||
n = n + 1
|
||||
}
|
||||
println[]
|
||||
|
||||
// Find the smallest non-representable positive sum
|
||||
sort[freq, {|a,b| a@0 <=> b@0}]
|
||||
last = 0
|
||||
for [num, count] = freq
|
||||
{
|
||||
if num > 0 and last+1 != num
|
||||
{
|
||||
println["Lowest non-representable positive sum is " + (last+1)]
|
||||
break
|
||||
}
|
||||
last = num
|
||||
}
|
||||
|
||||
// Find highest 10 representable numbers
|
||||
println["\nHighest representable numbers:"]
|
||||
size = length[freq]
|
||||
for i = size-10 to size-1
|
||||
println[freq@i@0]
|
||||
150
Task/Sum-to-100/Go/sum-to-100.go
Normal file
150
Task/Sum-to-100/Go/sum-to-100.go
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
const pow3_8 = 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 // 3^8
|
||||
const pow3_9 = 3 * pow3_8 // 3^9
|
||||
const maxExprs = 2 * pow3_8 // not 3^9 since first op can't be Join
|
||||
|
||||
type op uint8
|
||||
|
||||
const (
|
||||
Add op = iota // insert a "+"
|
||||
Sub // or a "-"
|
||||
Join // or just join together
|
||||
)
|
||||
|
||||
// code is an encoding of [9]op, the nine "operations"
|
||||
// we do on each each digit. The op for 1 is in
|
||||
// the highest bits, the op for 9 in the lowest.
|
||||
type code uint16
|
||||
|
||||
// evaluate 123456789 with + - or "" prepended to each as indicated by `c`.
|
||||
func (c code) evaluate() (sum int) {
|
||||
num, pow := 0, 1
|
||||
for k := 9; k >= 1; k-- {
|
||||
num += pow * k
|
||||
switch op(c % 3) {
|
||||
case Add:
|
||||
sum += num
|
||||
num, pow = 0, 1
|
||||
case Sub:
|
||||
sum -= num
|
||||
num, pow = 0, 1
|
||||
case Join:
|
||||
pow *= 10
|
||||
}
|
||||
c /= 3
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func (c code) String() string {
|
||||
buf := make([]byte, 0, 18)
|
||||
a, b := code(pow3_9), code(pow3_8)
|
||||
for k := 1; k <= 9; k++ {
|
||||
switch op((c % a) / b) {
|
||||
case Add:
|
||||
if k > 1 {
|
||||
buf = append(buf, '+')
|
||||
}
|
||||
case Sub:
|
||||
buf = append(buf, '-')
|
||||
}
|
||||
buf = append(buf, '0'+byte(k))
|
||||
a, b = b, b/3
|
||||
}
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
type sumCode struct {
|
||||
sum int
|
||||
code code
|
||||
}
|
||||
type sumCodes []sumCode
|
||||
|
||||
type sumCount struct {
|
||||
sum int
|
||||
count int
|
||||
}
|
||||
type sumCounts []sumCount
|
||||
|
||||
// For sorting (could also use sort.Slice with just Less).
|
||||
func (p sumCodes) Len() int { return len(p) }
|
||||
func (p sumCodes) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
func (p sumCodes) Less(i, j int) bool { return p[i].sum < p[j].sum }
|
||||
func (p sumCounts) Len() int { return len(p) }
|
||||
func (p sumCounts) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
func (p sumCounts) Less(i, j int) bool { return p[i].count > p[j].count }
|
||||
|
||||
// For printing.
|
||||
func (sc sumCode) String() string {
|
||||
return fmt.Sprintf("% 10d = %v", sc.sum, sc.code)
|
||||
}
|
||||
func (sc sumCount) String() string {
|
||||
return fmt.Sprintf("% 10d has %d solutions", sc.sum, sc.count)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Evaluate all expressions.
|
||||
expressions := make(sumCodes, 0, maxExprs/2)
|
||||
counts := make(sumCounts, 0, 1715)
|
||||
for c := code(0); c < maxExprs; c++ {
|
||||
// All negative sums are exactly like their positive
|
||||
// counterpart with all +/- switched, we don't need to
|
||||
// keep track of them.
|
||||
sum := c.evaluate()
|
||||
if sum >= 0 {
|
||||
expressions = append(expressions, sumCode{sum, c})
|
||||
}
|
||||
}
|
||||
sort.Sort(expressions)
|
||||
|
||||
// Count all unique sums
|
||||
sc := sumCount{expressions[0].sum, 1}
|
||||
for _, e := range expressions[1:] {
|
||||
if e.sum == sc.sum {
|
||||
sc.count++
|
||||
} else {
|
||||
counts = append(counts, sc)
|
||||
sc = sumCount{e.sum, 1}
|
||||
}
|
||||
}
|
||||
counts = append(counts, sc)
|
||||
sort.Sort(counts)
|
||||
|
||||
// Extract required results
|
||||
|
||||
fmt.Println("All solutions that sum to 100:")
|
||||
i := sort.Search(len(expressions), func(i int) bool {
|
||||
return expressions[i].sum >= 100
|
||||
})
|
||||
for _, e := range expressions[i:] {
|
||||
if e.sum != 100 {
|
||||
break
|
||||
}
|
||||
fmt.Println(e)
|
||||
}
|
||||
|
||||
fmt.Println("\nThe positive sum with maximum number of solutions:")
|
||||
fmt.Println(counts[0])
|
||||
|
||||
fmt.Println("\nThe lowest positive number that can't be expressed:")
|
||||
s := 1
|
||||
for _, e := range expressions {
|
||||
if e.sum == s {
|
||||
s++
|
||||
} else if e.sum > s {
|
||||
fmt.Printf("% 10d\n", s)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("\nThe ten highest numbers that can be expressed:")
|
||||
for _, e := range expressions[len(expressions)-10:] {
|
||||
fmt.Println(e)
|
||||
}
|
||||
}
|
||||
118
Task/Sum-to-100/Haskell/sum-to-100.hs
Normal file
118
Task/Sum-to-100/Haskell/sum-to-100.hs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
import Control.Monad (replicateM)
|
||||
import Data.Char (intToDigit)
|
||||
import Data.List
|
||||
( find,
|
||||
group,
|
||||
intercalate,
|
||||
nub,
|
||||
sort,
|
||||
sortBy,
|
||||
)
|
||||
import Data.Monoid ((<>))
|
||||
import Data.Ord (comparing)
|
||||
|
||||
data Sign
|
||||
= Unsigned
|
||||
| Plus
|
||||
| Minus
|
||||
deriving (Eq, Show)
|
||||
|
||||
------------------------ SUM TO 100 ----------------------
|
||||
|
||||
universe :: [[(Int, Sign)]]
|
||||
universe =
|
||||
zip [1 .. 9]
|
||||
<$> filter
|
||||
((/= Plus) . head)
|
||||
(replicateM 9 [Unsigned, Plus, Minus])
|
||||
|
||||
allNonNegativeSums :: [Int]
|
||||
allNonNegativeSums =
|
||||
sort $
|
||||
filter
|
||||
(>= 0)
|
||||
(asSum <$> universe)
|
||||
|
||||
uniqueNonNegativeSums :: [Int]
|
||||
uniqueNonNegativeSums = nub allNonNegativeSums
|
||||
|
||||
asSum :: [(Int, Sign)] -> Int
|
||||
asSum xs =
|
||||
n
|
||||
+ ( case s of
|
||||
[] -> 0
|
||||
_ -> read s :: Int
|
||||
)
|
||||
where
|
||||
(n, s) = foldr readSign (0, []) xs
|
||||
readSign ::
|
||||
(Int, Sign) ->
|
||||
(Int, String) ->
|
||||
(Int, String)
|
||||
readSign (i, x) (n, s)
|
||||
| x == Unsigned = (n, intToDigit i : s)
|
||||
| otherwise =
|
||||
( ( case x of
|
||||
Plus -> (+)
|
||||
_ -> (-)
|
||||
)
|
||||
n
|
||||
(read (show i <> s) :: Int),
|
||||
[]
|
||||
)
|
||||
|
||||
asString :: [(Int, Sign)] -> String
|
||||
asString = foldr signedDigit []
|
||||
where
|
||||
signedDigit (i, x) s
|
||||
| x == Unsigned = intToDigit i : s
|
||||
| otherwise =
|
||||
( case x of
|
||||
Plus -> " +"
|
||||
_ -> " -"
|
||||
)
|
||||
<> [intToDigit i]
|
||||
<> s
|
||||
|
||||
--------------------------- TEST -------------------------
|
||||
main :: IO ()
|
||||
main =
|
||||
putStrLn $
|
||||
unlines
|
||||
[ "Sums to 100:",
|
||||
unlines
|
||||
(asString <$> filter ((100 ==) . asSum) universe),
|
||||
"\n10 commonest sums (sum, number of routes to it):",
|
||||
show
|
||||
( ((,) <$> head <*> length)
|
||||
<$> take
|
||||
10
|
||||
( sortBy
|
||||
(flip (comparing length))
|
||||
(group allNonNegativeSums)
|
||||
)
|
||||
),
|
||||
"\nFirst positive integer not expressible "
|
||||
<> "as a sum of this kind:",
|
||||
maybeReport
|
||||
( find
|
||||
(uncurry (/=))
|
||||
(zip [0 ..] uniqueNonNegativeSums)
|
||||
),
|
||||
"\n10 largest sums:",
|
||||
show
|
||||
( take
|
||||
10
|
||||
( sortBy
|
||||
(flip compare)
|
||||
uniqueNonNegativeSums
|
||||
)
|
||||
)
|
||||
]
|
||||
where
|
||||
maybeReport ::
|
||||
Show a =>
|
||||
Maybe (a, b) ->
|
||||
String
|
||||
maybeReport (Just (x, _)) = show x
|
||||
maybeReport _ = "No gaps found"
|
||||
10
Task/Sum-to-100/J/sum-to-100.j
Normal file
10
Task/Sum-to-100/J/sum-to-100.j
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
p =: ,"2".>(#: (+ i.)2^8) <;.1 '123456789'
|
||||
m =. (9$_1x)^"1#:i.2^9
|
||||
s =. 131072 9 $ ,m *"1/ p
|
||||
s2 =: (~: (10x^i._9)#.s)#s
|
||||
ss =: +/"1 s2
|
||||
'100=';<'bp<+>' 8!:2 (I.100=ss){s2
|
||||
pos =: (0<ss)#ss =: /:~ss
|
||||
({.;'times';{:)>{.\:~(#,{.) each </.~ ss
|
||||
'Ten largest:';,.(->:i.10){ss
|
||||
'First not expressible:';>:pos{~ 1 i.~ 1<|2-/\pos
|
||||
168
Task/Sum-to-100/Java/sum-to-100.java
Normal file
168
Task/Sum-to-100/Java/sum-to-100.java
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* RossetaCode: Sum to 100, Java 8.
|
||||
*
|
||||
* Find solutions to the "sum to one hundred" puzzle.
|
||||
*/
|
||||
package rosettacode;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class SumTo100 implements Runnable {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SumTo100().run();
|
||||
}
|
||||
|
||||
void print(int givenSum) {
|
||||
Expression expression = new Expression();
|
||||
for (int i = 0; i < Expression.NUMBER_OF_EXPRESSIONS; i++, expression.next()) {
|
||||
if (expression.toInt() == givenSum) {
|
||||
expression.print();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void comment(String commentString) {
|
||||
System.out.println();
|
||||
System.out.println(commentString);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final Stat stat = new Stat();
|
||||
|
||||
comment("Show all solutions that sum to 100");
|
||||
final int givenSum = 100;
|
||||
print(givenSum);
|
||||
|
||||
comment("Show the sum that has the maximum number of solutions");
|
||||
final int maxCount = Collections.max(stat.sumCount.keySet());
|
||||
int maxSum;
|
||||
Iterator<Integer> it = stat.sumCount.get(maxCount).iterator();
|
||||
do {
|
||||
maxSum = it.next();
|
||||
} while (maxSum < 0);
|
||||
System.out.println(maxSum + " has " + maxCount + " solutions");
|
||||
|
||||
comment("Show the lowest positive number that can't be expressed");
|
||||
int value = 0;
|
||||
while (stat.countSum.containsKey(value)) {
|
||||
value++;
|
||||
}
|
||||
System.out.println(value);
|
||||
|
||||
comment("Show the ten highest numbers that can be expressed");
|
||||
final int n = stat.countSum.keySet().size();
|
||||
final Integer[] sums = stat.countSum.keySet().toArray(new Integer[n]);
|
||||
Arrays.sort(sums);
|
||||
for (int i = n - 1; i >= n - 10; i--) {
|
||||
print(sums[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Expression {
|
||||
|
||||
private final static int NUMBER_OF_DIGITS = 9;
|
||||
private final static byte ADD = 0;
|
||||
private final static byte SUB = 1;
|
||||
private final static byte JOIN = 2;
|
||||
|
||||
final byte[] code = new byte[NUMBER_OF_DIGITS];
|
||||
final static int NUMBER_OF_EXPRESSIONS = 2 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3;
|
||||
|
||||
Expression next() {
|
||||
for (int i = 0; i < NUMBER_OF_DIGITS; i++) {
|
||||
if (++code[i] > JOIN) {
|
||||
code[i] = ADD;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
int toInt() {
|
||||
int value = 0;
|
||||
int number = 0;
|
||||
int sign = (+1);
|
||||
for (int digit = 1; digit <= 9; digit++) {
|
||||
switch (code[NUMBER_OF_DIGITS - digit]) {
|
||||
case ADD:
|
||||
value += sign * number;
|
||||
number = digit;
|
||||
sign = (+1);
|
||||
break;
|
||||
case SUB:
|
||||
value += sign * number;
|
||||
number = digit;
|
||||
sign = (-1);
|
||||
break;
|
||||
case JOIN:
|
||||
number = 10 * number + digit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return value + sign * number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder(2 * NUMBER_OF_DIGITS + 1);
|
||||
for (int digit = 1; digit <= NUMBER_OF_DIGITS; digit++) {
|
||||
switch (code[NUMBER_OF_DIGITS - digit]) {
|
||||
case ADD:
|
||||
if (digit > 1) {
|
||||
s.append('+');
|
||||
}
|
||||
break;
|
||||
case SUB:
|
||||
s.append('-');
|
||||
break;
|
||||
}
|
||||
s.append(digit);
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
void print() {
|
||||
print(System.out);
|
||||
}
|
||||
|
||||
void print(PrintStream printStream) {
|
||||
printStream.format("%9d", this.toInt());
|
||||
printStream.println(" = " + this);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Stat {
|
||||
|
||||
final Map<Integer, Integer> countSum = new HashMap<>();
|
||||
final Map<Integer, Set<Integer>> sumCount = new HashMap<>();
|
||||
|
||||
Stat() {
|
||||
Expression expression = new Expression();
|
||||
for (int i = 0; i < Expression.NUMBER_OF_EXPRESSIONS; i++, expression.next()) {
|
||||
int sum = expression.toInt();
|
||||
countSum.put(sum, countSum.getOrDefault(sum, 0) + 1);
|
||||
}
|
||||
for (Map.Entry<Integer, Integer> entry : countSum.entrySet()) {
|
||||
Set<Integer> set;
|
||||
if (sumCount.containsKey(entry.getValue())) {
|
||||
set = sumCount.get(entry.getValue());
|
||||
} else {
|
||||
set = new HashSet<>();
|
||||
}
|
||||
set.add(entry.getKey());
|
||||
sumCount.put(entry.getValue(), set);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
227
Task/Sum-to-100/JavaScript/sum-to-100-1.js
Normal file
227
Task/Sum-to-100/JavaScript/sum-to-100-1.js
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
// GENERIC FUNCTIONS ----------------------------------------------------
|
||||
|
||||
// permutationsWithRepetition :: Int -> [a] -> [[a]]
|
||||
var permutationsWithRepetition = function (n, as) {
|
||||
return as.length > 0 ?
|
||||
foldl1(curry(cartesianProduct)(as), replicate(n, as)) : [];
|
||||
};
|
||||
|
||||
// cartesianProduct :: [a] -> [b] -> [[a, b]]
|
||||
var cartesianProduct = function (xs, ys) {
|
||||
return [].concat.apply([], xs.map(function (x) {
|
||||
return [].concat.apply([], ys.map(function (y) {
|
||||
return [
|
||||
[x].concat(y)
|
||||
];
|
||||
}));
|
||||
}));
|
||||
};
|
||||
|
||||
// curry :: ((a, b) -> c) -> a -> b -> c
|
||||
var curry = function (f) {
|
||||
return function (a) {
|
||||
return function (b) {
|
||||
return f(a, b);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// flip :: (a -> b -> c) -> b -> a -> c
|
||||
var flip = function (f) {
|
||||
return function (a, b) {
|
||||
return f.apply(null, [b, a]);
|
||||
};
|
||||
};
|
||||
|
||||
// foldl1 :: (a -> a -> a) -> [a] -> a
|
||||
var foldl1 = function (f, xs) {
|
||||
return xs.length > 0 ? xs.slice(1)
|
||||
.reduce(f, xs[0]) : [];
|
||||
};
|
||||
|
||||
// replicate :: Int -> a -> [a]
|
||||
var replicate = function (n, a) {
|
||||
var v = [a],
|
||||
o = [];
|
||||
if (n < 1) return o;
|
||||
while (n > 1) {
|
||||
if (n & 1) o = o.concat(v);
|
||||
n >>= 1;
|
||||
v = v.concat(v);
|
||||
}
|
||||
return o.concat(v);
|
||||
};
|
||||
|
||||
// group :: Eq a => [a] -> [[a]]
|
||||
var group = function (xs) {
|
||||
return groupBy(function (a, b) {
|
||||
return a === b;
|
||||
}, xs);
|
||||
};
|
||||
|
||||
// groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
|
||||
var groupBy = function (f, xs) {
|
||||
var dct = xs.slice(1)
|
||||
.reduce(function (a, x) {
|
||||
var h = a.active.length > 0 ? a.active[0] : undefined,
|
||||
blnGroup = h !== undefined && f(h, x);
|
||||
|
||||
return {
|
||||
active: blnGroup ? a.active.concat(x) : [x],
|
||||
sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])
|
||||
};
|
||||
}, {
|
||||
active: xs.length > 0 ? [xs[0]] : [],
|
||||
sofar: []
|
||||
});
|
||||
return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);
|
||||
};
|
||||
|
||||
// compare :: a -> a -> Ordering
|
||||
var compare = function (a, b) {
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
};
|
||||
|
||||
// on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
|
||||
var on = function (f, g) {
|
||||
return function (a, b) {
|
||||
return f(g(a), g(b));
|
||||
};
|
||||
};
|
||||
|
||||
// nub :: [a] -> [a]
|
||||
var nub = function (xs) {
|
||||
return nubBy(function (a, b) {
|
||||
return a === b;
|
||||
}, xs);
|
||||
};
|
||||
|
||||
// nubBy :: (a -> a -> Bool) -> [a] -> [a]
|
||||
var nubBy = function (p, xs) {
|
||||
var x = xs.length ? xs[0] : undefined;
|
||||
|
||||
return x !== undefined ? [x].concat(nubBy(p, xs.slice(1)
|
||||
.filter(function (y) {
|
||||
return !p(x, y);
|
||||
}))) : [];
|
||||
};
|
||||
|
||||
// find :: (a -> Bool) -> [a] -> Maybe a
|
||||
var find = function (f, xs) {
|
||||
for (var i = 0, lng = xs.length; i < lng; i++) {
|
||||
if (f(xs[i], i)) return xs[i];
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
// Int -> [a] -> [a]
|
||||
var take = function (n, xs) {
|
||||
return xs.slice(0, n);
|
||||
};
|
||||
|
||||
// unlines :: [String] -> String
|
||||
var unlines = function (xs) {
|
||||
return xs.join('\n');
|
||||
};
|
||||
|
||||
// show :: a -> String
|
||||
var show = function (x) {
|
||||
return JSON.stringify(x);
|
||||
}; //, null, 2);
|
||||
|
||||
// head :: [a] -> a
|
||||
var head = function (xs) {
|
||||
return xs.length ? xs[0] : undefined;
|
||||
};
|
||||
|
||||
// tail :: [a] -> [a]
|
||||
var tail = function (xs) {
|
||||
return xs.length ? xs.slice(1) : undefined;
|
||||
};
|
||||
|
||||
// length :: [a] -> Int
|
||||
var length = function (xs) {
|
||||
return xs.length;
|
||||
};
|
||||
|
||||
// SIGNED DIGIT SEQUENCES (mapped to sums and to strings)
|
||||
|
||||
// data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )
|
||||
// asSum :: [Sign] -> Int
|
||||
var asSum = function (xs) {
|
||||
var dct = xs.reduceRight(function (a, sign, i) {
|
||||
var d = i + 1; // zero-based index to [1-9] positions
|
||||
if (sign !== 0) {
|
||||
// Sum increased, digits cleared
|
||||
return {
|
||||
digits: [],
|
||||
n: a.n + sign * parseInt([d].concat(a.digits)
|
||||
.join(''), 10)
|
||||
};
|
||||
} else return { // Digits extended, sum unchanged
|
||||
digits: [d].concat(a.digits),
|
||||
n: a.n
|
||||
};
|
||||
}, {
|
||||
digits: [],
|
||||
n: 0
|
||||
});
|
||||
return dct.n + (
|
||||
dct.digits.length > 0 ? parseInt(dct.digits.join(''), 10) : 0
|
||||
);
|
||||
};
|
||||
|
||||
// data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )
|
||||
// asString :: [Sign] -> String
|
||||
var asString = function (xs) {
|
||||
var ns = xs.reduce(function (a, sign, i) {
|
||||
var d = (i + 1)
|
||||
.toString();
|
||||
return sign === 0 ? a + d : a + (sign > 0 ? ' +' : ' -') + d;
|
||||
}, '');
|
||||
|
||||
return ns[0] === '+' ? tail(ns) : ns;
|
||||
};
|
||||
|
||||
// SUM T0 100 ------------------------------------------------------------
|
||||
|
||||
// universe :: [[Sign]]
|
||||
var universe = permutationsWithRepetition(9, [0, 1, -1])
|
||||
.filter(function (x) {
|
||||
return x[0] !== 1;
|
||||
});
|
||||
|
||||
// allNonNegativeSums :: [Int]
|
||||
var allNonNegativeSums = universe.map(asSum)
|
||||
.filter(function (x) {
|
||||
return x >= 0;
|
||||
})
|
||||
.sort();
|
||||
|
||||
// uniqueNonNegativeSums :: [Int]
|
||||
var uniqueNonNegativeSums = nub(allNonNegativeSums);
|
||||
|
||||
return ["Sums to 100:\n", unlines(universe.filter(function (x) {
|
||||
return asSum(x) === 100;
|
||||
})
|
||||
.map(asString)),
|
||||
|
||||
"\n\n10 commonest sums (sum, followed by number of routes to it):\n",
|
||||
show(take(10, group(allNonNegativeSums)
|
||||
.sort(on(flip(compare), length))
|
||||
.map(function (xs) {
|
||||
return [xs[0], xs.length];
|
||||
}))),
|
||||
|
||||
"\n\nFirst positive integer not expressible as a sum of this kind:\n",
|
||||
show(find(function (x, i) {
|
||||
return x !== i;
|
||||
}, uniqueNonNegativeSums.sort(compare)) - 1), // zero-based index
|
||||
|
||||
"\n10 largest sums:\n",
|
||||
show(take(10, uniqueNonNegativeSums.sort(flip(compare))))
|
||||
].join('\n') + '\n';
|
||||
})();
|
||||
184
Task/Sum-to-100/JavaScript/sum-to-100-2.js
Normal file
184
Task/Sum-to-100/JavaScript/sum-to-100-2.js
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// GENERIC FUNCTIONS ----------------------------------------------------
|
||||
|
||||
// permutationsWithRepetition :: Int -> [a] -> [[a]]
|
||||
const permutationsWithRepetition = (n, as) =>
|
||||
as.length > 0 ? (
|
||||
foldl1(curry(cartesianProduct)(as), replicate(n, as))
|
||||
) : [];
|
||||
|
||||
// cartesianProduct :: [a] -> [b] -> [[a, b]]
|
||||
const cartesianProduct = (xs, ys) =>
|
||||
[].concat.apply([], xs.map(x =>
|
||||
[].concat.apply([], ys.map(y => [[x].concat(y)]))));
|
||||
|
||||
// curry :: ((a, b) -> c) -> a -> b -> c
|
||||
const curry = f => a => b => f(a, b);
|
||||
|
||||
// flip :: (a -> b -> c) -> b -> a -> c
|
||||
const flip = f => (a, b) => f.apply(null, [b, a]);
|
||||
|
||||
// foldl1 :: (a -> a -> a) -> [a] -> a
|
||||
const foldl1 = (f, xs) =>
|
||||
xs.length > 0 ? xs.slice(1)
|
||||
.reduce(f, xs[0]) : [];
|
||||
|
||||
// replicate :: Int -> a -> [a]
|
||||
const replicate = (n, a) => {
|
||||
let v = [a],
|
||||
o = [];
|
||||
if (n < 1) return o;
|
||||
while (n > 1) {
|
||||
if (n & 1) o = o.concat(v);
|
||||
n >>= 1;
|
||||
v = v.concat(v);
|
||||
}
|
||||
return o.concat(v);
|
||||
};
|
||||
|
||||
// group :: Eq a => [a] -> [[a]]
|
||||
const group = xs => groupBy((a, b) => a === b, xs);
|
||||
|
||||
// groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
|
||||
const groupBy = (f, xs) => {
|
||||
const dct = xs.slice(1)
|
||||
.reduce((a, x) => {
|
||||
const
|
||||
h = a.active.length > 0 ? a.active[0] : undefined,
|
||||
blnGroup = h !== undefined && f(h, x);
|
||||
|
||||
return {
|
||||
active: blnGroup ? a.active.concat(x) : [x],
|
||||
sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])
|
||||
};
|
||||
}, {
|
||||
active: xs.length > 0 ? [xs[0]] : [],
|
||||
sofar: []
|
||||
});
|
||||
return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);
|
||||
};
|
||||
|
||||
// compare :: a -> a -> Ordering
|
||||
const compare = (a, b) => a < b ? -1 : (a > b ? 1 : 0);
|
||||
|
||||
// on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
|
||||
const on = (f, g) => (a, b) => f(g(a), g(b));
|
||||
|
||||
// nub :: [a] -> [a]
|
||||
const nub = xs => nubBy((a, b) => a === b, xs);
|
||||
|
||||
// nubBy :: (a -> a -> Bool) -> [a] -> [a]
|
||||
const nubBy = (p, xs) => {
|
||||
const x = xs.length ? xs[0] : undefined;
|
||||
|
||||
return x !== undefined ? [x].concat(
|
||||
nubBy(p, xs.slice(1)
|
||||
.filter(y => !p(x, y)))
|
||||
) : [];
|
||||
};
|
||||
|
||||
// find :: (a -> Bool) -> [a] -> Maybe a
|
||||
const find = (f, xs) => {
|
||||
for (var i = 0, lng = xs.length; i < lng; i++) {
|
||||
if (f(xs[i], i)) return xs[i];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Int -> [a] -> [a]
|
||||
const take = (n, xs) => xs.slice(0, n);
|
||||
|
||||
// unlines :: [String] -> String
|
||||
const unlines = xs => xs.join('\n');
|
||||
|
||||
// show :: a -> String
|
||||
const show = x => JSON.stringify(x); //, null, 2);
|
||||
|
||||
// head :: [a] -> a
|
||||
const head = xs => xs.length ? xs[0] : undefined;
|
||||
|
||||
// tail :: [a] -> [a]
|
||||
const tail = xs => xs.length ? xs.slice(1) : undefined;
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs => xs.length;
|
||||
|
||||
|
||||
// SIGNED DIGIT SEQUENCES (mapped to sums and to strings)
|
||||
|
||||
// data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )
|
||||
// asSum :: [Sign] -> Int
|
||||
const asSum = xs => {
|
||||
const dct = xs.reduceRight((a, sign, i) => {
|
||||
const d = i + 1; // zero-based index to [1-9] positions
|
||||
if (sign !== 0) { // Sum increased, digits cleared
|
||||
return {
|
||||
digits: [],
|
||||
n: a.n + (sign * parseInt([d].concat(a.digits)
|
||||
.join(''), 10))
|
||||
};
|
||||
} else return { // Digits extended, sum unchanged
|
||||
digits: [d].concat(a.digits),
|
||||
n: a.n
|
||||
};
|
||||
}, {
|
||||
digits: [],
|
||||
n: 0
|
||||
});
|
||||
return dct.n + (dct.digits.length > 0 ? (
|
||||
parseInt(dct.digits.join(''), 10)
|
||||
) : 0);
|
||||
};
|
||||
|
||||
// data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )
|
||||
// asString :: [Sign] -> String
|
||||
const asString = xs => {
|
||||
const ns = xs.reduce((a, sign, i) => {
|
||||
const d = (i + 1)
|
||||
.toString();
|
||||
return (sign === 0 ? (
|
||||
a + d
|
||||
) : (a + (sign > 0 ? ' +' : ' -') + d));
|
||||
}, '');
|
||||
|
||||
return ns[0] === '+' ? tail(ns) : ns;
|
||||
};
|
||||
|
||||
|
||||
// SUM T0 100 ------------------------------------------------------------
|
||||
|
||||
// universe :: [[Sign]]
|
||||
const universe = permutationsWithRepetition(9, [0, 1, -1])
|
||||
.filter(x => x[0] !== 1);
|
||||
|
||||
// allNonNegativeSums :: [Int]
|
||||
const allNonNegativeSums = universe.map(asSum)
|
||||
.filter(x => x >= 0)
|
||||
.sort();
|
||||
|
||||
// uniqueNonNegativeSums :: [Int]
|
||||
const uniqueNonNegativeSums = nub(allNonNegativeSums);
|
||||
|
||||
|
||||
return [
|
||||
"Sums to 100:\n",
|
||||
unlines(universe.filter(x => asSum(x) === 100)
|
||||
.map(asString)),
|
||||
|
||||
"\n\n10 commonest sums (sum, followed by number of routes to it):\n",
|
||||
show(take(10, group(allNonNegativeSums)
|
||||
.sort(on(flip(compare), length))
|
||||
.map(xs => [xs[0], xs.length]))),
|
||||
|
||||
"\n\nFirst positive integer not expressible as a sum of this kind:\n",
|
||||
show(find(
|
||||
(x, i) => x !== i,
|
||||
uniqueNonNegativeSums.sort(compare)
|
||||
) - 1), // i is the the zero-based Array index.
|
||||
|
||||
"\n10 largest sums:\n",
|
||||
show(take(10, uniqueNonNegativeSums.sort(flip(compare))))
|
||||
].join('\n') + '\n';
|
||||
})();
|
||||
122
Task/Sum-to-100/JavaScript/sum-to-100-3.js
Normal file
122
Task/Sum-to-100/JavaScript/sum-to-100-3.js
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
SumTo100();
|
||||
|
||||
function SumTo100()
|
||||
{
|
||||
var
|
||||
ADD = 0,
|
||||
SUB = 1,
|
||||
JOIN = 2;
|
||||
|
||||
var
|
||||
nexpr = 13122;
|
||||
|
||||
function out(something)
|
||||
{
|
||||
WScript.Echo(something);
|
||||
}
|
||||
|
||||
function evaluate(code)
|
||||
{
|
||||
var
|
||||
value = 0,
|
||||
number = 0,
|
||||
power = 1;
|
||||
|
||||
for ( var k = 9; k >= 1; k-- )
|
||||
{
|
||||
number = power*k + number;
|
||||
switch( code % 3 )
|
||||
{
|
||||
case ADD: value = value + number; number = 0; power = 1; break;
|
||||
case SUB: value = value - number; number = 0; power = 1; break;
|
||||
case JOIN: power = power * 10 ; break;
|
||||
}
|
||||
code = Math.floor(code/3);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function print(code)
|
||||
{
|
||||
var
|
||||
s = "";
|
||||
var
|
||||
a = 19683,
|
||||
b = 6561;
|
||||
|
||||
for ( var k = 1; k <= 9; k++ )
|
||||
{
|
||||
switch( Math.floor( (code % a) / b ) ){
|
||||
case ADD: if ( k > 1 ) s = s + '+'; break;
|
||||
case SUB: s = s + '-'; break;
|
||||
}
|
||||
a = b;
|
||||
b = Math.floor(b/3);
|
||||
s = s + String.fromCharCode(0x30+k);
|
||||
}
|
||||
out(evaluate(code) + " = " + s);
|
||||
}
|
||||
|
||||
function comment(commentString)
|
||||
{
|
||||
out("");
|
||||
out(commentString);
|
||||
out("");
|
||||
}
|
||||
|
||||
comment("Show all solutions that sum to 100");
|
||||
for ( var i = 0; i < nexpr; i++)
|
||||
if ( evaluate(i) == 100 )
|
||||
print(i);
|
||||
|
||||
comment("Show the sum that has the maximum number of solutions");
|
||||
var stat = {};
|
||||
for ( var i = 0; i < nexpr; i++ )
|
||||
{
|
||||
var sum = evaluate(i);
|
||||
if (stat[sum])
|
||||
stat[sum]++;
|
||||
else
|
||||
stat[sum] = 1;
|
||||
}
|
||||
|
||||
var best = 0;
|
||||
var nbest = -1;
|
||||
for ( var i = 0; i < nexpr; i++ )
|
||||
{
|
||||
var sum = evaluate(i);
|
||||
if ( sum > 0 )
|
||||
if ( stat[sum] > nbest )
|
||||
{
|
||||
best = i;
|
||||
nbest = stat[sum];
|
||||
}
|
||||
}
|
||||
out("" + evaluate(best) + " has " + nbest + " solutions");
|
||||
|
||||
comment("Show the lowest positive number that can't be expressed");
|
||||
for ( var i = 0; i <= 123456789; i++ )
|
||||
{
|
||||
for ( var j = 0; j < nexpr; j++)
|
||||
if ( i == evaluate(j) ) break;
|
||||
if ( i != evaluate(j) ) break;
|
||||
}
|
||||
out(i);
|
||||
|
||||
comment("Show the ten highest numbers that can be expressed");
|
||||
var limit = 123456789 + 1;
|
||||
for ( i = 1; i <= 10; i++ )
|
||||
{
|
||||
var best = 0;
|
||||
for ( var j = 0; j < nexpr; j++)
|
||||
{
|
||||
var test = evaluate(j);
|
||||
if ( test < limit && test > best )
|
||||
best = test;
|
||||
}
|
||||
for ( var j = 0; j < nexpr; j++)
|
||||
if ( evaluate(j) == best ) print(j);
|
||||
limit = best;
|
||||
}
|
||||
|
||||
}
|
||||
20
Task/Sum-to-100/Jq/sum-to-100-1.jq
Normal file
20
Task/Sum-to-100/Jq/sum-to-100-1.jq
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Generate a "sum" in the form: [I, 1, X, 2, X, 3, ..., X, n] where I is "-" or "", and X is "+", "-", or ""
|
||||
def generate(n):
|
||||
def pm: ["+"], ["-"], [""];
|
||||
|
||||
if n == 1 then (["-"], [""]) + [1]
|
||||
else generate(n-1) + pm + [n]
|
||||
end;
|
||||
|
||||
# The numerical value of a "sum"
|
||||
def addup:
|
||||
reduce .[] as $x ({sum:0, previous: "0"};
|
||||
if $x == "+" then .sum += (.previous|tonumber) | .previous = ""
|
||||
elif $x == "-" then .sum += (.previous|tonumber) | .previous = "-"
|
||||
elif $x == "" then .
|
||||
else .previous += ($x|tostring)
|
||||
end)
|
||||
| .sum + (.previous | tonumber) ;
|
||||
|
||||
# Pretty-print a "sum", e.g. ["",1,"+", 2] => 1 + 2
|
||||
def pp: map(if . == "+" or . == "-" then " " + . else tostring end) | join("");
|
||||
1
Task/Sum-to-100/Jq/sum-to-100-2.jq
Normal file
1
Task/Sum-to-100/Jq/sum-to-100-2.jq
Normal file
|
|
@ -0,0 +1 @@
|
|||
generate(9) | select(addup == 100) | pp
|
||||
9
Task/Sum-to-100/Jq/sum-to-100-3.jq
Normal file
9
Task/Sum-to-100/Jq/sum-to-100-3.jq
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
def histogram(s): reduce s as $x ({}; ($x|tostring) as $k | .[$k] += 1);
|
||||
|
||||
# Emit an array of [ value, frequency ] pairs
|
||||
def greatest(n):
|
||||
to_entries
|
||||
| map( [.key, .value] )
|
||||
| sort_by(.[1])
|
||||
| .[(length-n):]
|
||||
| reverse ;
|
||||
1
Task/Sum-to-100/Jq/sum-to-100-4.jq
Normal file
1
Task/Sum-to-100/Jq/sum-to-100-4.jq
Normal file
|
|
@ -0,0 +1 @@
|
|||
histogram(generate(9) | addup | select(.>0)) | greatest(1)
|
||||
1
Task/Sum-to-100/Jq/sum-to-100-5.jq
Normal file
1
Task/Sum-to-100/Jq/sum-to-100-5.jq
Normal file
|
|
@ -0,0 +1 @@
|
|||
histogram(generate(9) | addup | select(.>0)) | greatest(1)
|
||||
6
Task/Sum-to-100/Jq/sum-to-100-6.jq
Normal file
6
Task/Sum-to-100/Jq/sum-to-100-6.jq
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
def first_missing(s):
|
||||
first( foreach s as $i (null;
|
||||
if . == null or $i == . or $i == .+1 then $i else [.+1] end;
|
||||
select(type == "array") | .[0]));
|
||||
|
||||
first_missing( [generate(9) | addup | select(.>0) ] | unique[])
|
||||
1
Task/Sum-to-100/Jq/sum-to-100-7.jq
Normal file
1
Task/Sum-to-100/Jq/sum-to-100-7.jq
Normal file
|
|
@ -0,0 +1 @@
|
|||
[generate(9) | addup | select(.>0)] | unique | .[(length-10):]
|
||||
58
Task/Sum-to-100/Julia/sum-to-100.julia
Normal file
58
Task/Sum-to-100/Julia/sum-to-100.julia
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
using Printf, IterTools, DataStructures
|
||||
|
||||
expr(p::String...)::String = @sprintf("%s1%s2%s3%s4%s5%s6%s7%s8%s9", p...)
|
||||
function genexpr()::Vector{String}
|
||||
op = ["+", "-", ""]
|
||||
return collect(expr(p...) for (p) in Iterators.product(op, op, op, op, op, op, op, op, op) if p[1] != "+")
|
||||
end
|
||||
|
||||
using DataStructures
|
||||
|
||||
function allexpr()::Dict{Int,Int}
|
||||
rst = DefaultDict{Int,Int}(0)
|
||||
for e in genexpr()
|
||||
val = eval(Meta.parse(e))
|
||||
rst[val] += 1
|
||||
end
|
||||
return rst
|
||||
end
|
||||
|
||||
sumto(val::Int)::Vector{String} = filter(e -> eval(Meta.parse(e)) == val, genexpr())
|
||||
function maxsolve()::Dict{Int,Int}
|
||||
ae = allexpr()
|
||||
vmax = maximum(values(ae))
|
||||
smax = filter(ae) do (v, f)
|
||||
f == vmax
|
||||
end
|
||||
return smax
|
||||
end
|
||||
function minsolve()::Int
|
||||
ae = keys(allexpr())
|
||||
for i in 1:typemax(Int)
|
||||
if i ∉ ae
|
||||
return i
|
||||
end
|
||||
end
|
||||
end
|
||||
function highestsums(n::Int)::Vector{Int}
|
||||
sums = collect(keys(allexpr()))
|
||||
return sort!(sums; rev=true)[1:n]
|
||||
end
|
||||
|
||||
const solutions = sumto(100)
|
||||
const smax = maxsolve()
|
||||
const smin = minsolve()
|
||||
const hsums = highestsums(10)
|
||||
|
||||
println("100 =")
|
||||
foreach(println, solutions)
|
||||
|
||||
println("\nMax number of solutions:")
|
||||
for (v, f) in smax
|
||||
@printf("%3i -> %2i\n", v, f)
|
||||
end
|
||||
|
||||
println("\nMin number with no solutions: $smin")
|
||||
|
||||
println("\nHighest sums representable:")
|
||||
foreach(println, hsums)
|
||||
101
Task/Sum-to-100/Kotlin/sum-to-100.kotlin
Normal file
101
Task/Sum-to-100/Kotlin/sum-to-100.kotlin
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// version 1.1.51
|
||||
|
||||
class Expression {
|
||||
|
||||
private enum class Op { ADD, SUB, JOIN }
|
||||
private val code = Array<Op>(NUMBER_OF_DIGITS) { Op.ADD }
|
||||
|
||||
companion object {
|
||||
private const val NUMBER_OF_DIGITS = 9
|
||||
private const val THREE_POW_4 = 3 * 3 * 3 * 3
|
||||
private const val FMT = "%9d"
|
||||
const val NUMBER_OF_EXPRESSIONS = 2 * THREE_POW_4 * THREE_POW_4
|
||||
|
||||
fun print(givenSum: Int) {
|
||||
var expression = Expression()
|
||||
repeat(Expression.NUMBER_OF_EXPRESSIONS) {
|
||||
if (expression.toInt() == givenSum) println("${FMT.format(givenSum)} = $expression")
|
||||
expression++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operator fun inc(): Expression {
|
||||
for (i in 0 until code.size) {
|
||||
code[i] = when (code[i]) {
|
||||
Op.ADD -> Op.SUB
|
||||
Op.SUB -> Op.JOIN
|
||||
Op.JOIN -> Op.ADD
|
||||
}
|
||||
if (code[i] != Op.ADD) break
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun toInt(): Int {
|
||||
var value = 0
|
||||
var number = 0
|
||||
var sign = +1
|
||||
for (digit in 1..9) {
|
||||
when (code[NUMBER_OF_DIGITS - digit]) {
|
||||
Op.ADD -> { value += sign * number; number = digit; sign = +1 }
|
||||
Op.SUB -> { value += sign * number; number = digit; sign = -1 }
|
||||
Op.JOIN -> { number = 10 * number + digit }
|
||||
}
|
||||
}
|
||||
return value + sign * number
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val sb = StringBuilder()
|
||||
for (digit in 1..NUMBER_OF_DIGITS) {
|
||||
when (code[NUMBER_OF_DIGITS - digit]) {
|
||||
Op.ADD -> if (digit > 1) sb.append(" + ")
|
||||
Op.SUB -> sb.append(" - ")
|
||||
Op.JOIN -> {}
|
||||
}
|
||||
sb.append(digit)
|
||||
}
|
||||
return sb.toString().trimStart()
|
||||
}
|
||||
}
|
||||
|
||||
class Stat {
|
||||
|
||||
val countSum = mutableMapOf<Int, Int>()
|
||||
val sumCount = mutableMapOf<Int, MutableSet<Int>>()
|
||||
|
||||
init {
|
||||
var expression = Expression()
|
||||
repeat (Expression.NUMBER_OF_EXPRESSIONS) {
|
||||
val sum = expression.toInt()
|
||||
countSum.put(sum, 1 + (countSum[sum] ?: 0))
|
||||
expression++
|
||||
}
|
||||
for ((k, v) in countSum) {
|
||||
val set = if (sumCount.containsKey(v))
|
||||
sumCount[v]!!
|
||||
else
|
||||
mutableSetOf<Int>()
|
||||
set.add(k)
|
||||
sumCount.put(v, set)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println("100 has the following solutions:\n")
|
||||
Expression.print(100)
|
||||
|
||||
val stat = Stat()
|
||||
val maxCount = stat.sumCount.keys.max()
|
||||
val maxSum = stat.sumCount[maxCount]!!.max()
|
||||
println("\n$maxSum has the maximum number of solutions, namely $maxCount")
|
||||
|
||||
var value = 0
|
||||
while (stat.countSum.containsKey(value)) value++
|
||||
println("\n$value is the lowest positive number with no solutions")
|
||||
|
||||
println("\nThe ten highest numbers that do have solutions are:\n")
|
||||
stat.countSum.keys.toIntArray().sorted().reversed().take(10).forEach { Expression.print(it) }
|
||||
}
|
||||
123
Task/Sum-to-100/Lua/sum-to-100.lua
Normal file
123
Task/Sum-to-100/Lua/sum-to-100.lua
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
local expressionsLength = 0
|
||||
function compareExpressionBySum(a, b)
|
||||
return a.sum - b.sum
|
||||
end
|
||||
|
||||
local countSumsLength = 0
|
||||
function compareCountSumsByCount(a, b)
|
||||
return a.counts - b.counts
|
||||
end
|
||||
|
||||
function evaluate(code)
|
||||
local value = 0
|
||||
local number = 0
|
||||
local power = 1
|
||||
for k=9,1,-1 do
|
||||
number = power*k + number
|
||||
local mod = code % 3
|
||||
if mod == 0 then
|
||||
-- ADD
|
||||
value = value + number
|
||||
number = 0
|
||||
power = 1
|
||||
elseif mod == 1 then
|
||||
-- SUB
|
||||
value = value - number
|
||||
number = 0
|
||||
power = 1
|
||||
elseif mod == 2 then
|
||||
-- JOIN
|
||||
power = 10 * power
|
||||
else
|
||||
print("This should not happen.")
|
||||
end
|
||||
code = math.floor(code / 3)
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
function printCode(code)
|
||||
local a = 19683
|
||||
local b = 6561
|
||||
local s = ""
|
||||
for k=1,9 do
|
||||
local temp = math.floor((code % a) / b)
|
||||
if temp == 0 then
|
||||
-- ADD
|
||||
if k>1 then
|
||||
s = s .. '+'
|
||||
end
|
||||
elseif temp == 1 then
|
||||
-- SUB
|
||||
s = s .. '-'
|
||||
end
|
||||
a = b
|
||||
b = math.floor(b/3)
|
||||
s = s .. tostring(k)
|
||||
end
|
||||
print("\t"..evaluate(code).." = "..s)
|
||||
end
|
||||
|
||||
-- Main
|
||||
local nexpr = 13122
|
||||
|
||||
print("Show all solutions that sum to 100")
|
||||
for i=0,nexpr-1 do
|
||||
if evaluate(i) == 100 then
|
||||
printCode(i)
|
||||
end
|
||||
end
|
||||
print()
|
||||
|
||||
print("Show the sum that has the maximum number of solutions")
|
||||
local nbest = -1
|
||||
for i=0,nexpr-1 do
|
||||
local test = evaluate(i)
|
||||
if test>0 then
|
||||
local ntest = 0
|
||||
for j=0,nexpr-1 do
|
||||
if evaluate(j) == test then
|
||||
ntest = ntest + 1
|
||||
end
|
||||
if ntest > nbest then
|
||||
best = test
|
||||
nbest = ntest
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
print(best.." has "..nbest.." solutions\n")
|
||||
|
||||
print("Show the lowest positive number that can't be expressed")
|
||||
local code = -1
|
||||
for i=0,123456789 do
|
||||
for j=0,nexpr-1 do
|
||||
if evaluate(j) == i then
|
||||
code = j
|
||||
break
|
||||
end
|
||||
end
|
||||
if evaluate(code) ~= i then
|
||||
code = i
|
||||
break
|
||||
end
|
||||
end
|
||||
print(code.."\n")
|
||||
|
||||
print("Show the ten highest numbers that can be expressed")
|
||||
local limit = 123456789 + 1
|
||||
for i=1,10 do
|
||||
local best=0
|
||||
for j=0,nexpr-1 do
|
||||
local test = evaluate(j)
|
||||
if (test<limit) and (test>best) then
|
||||
best = test
|
||||
end
|
||||
end
|
||||
for j=0,nexpr-1 do
|
||||
if evaluate(j) == best then
|
||||
printCode(j)
|
||||
end
|
||||
end
|
||||
limit = best
|
||||
end
|
||||
2
Task/Sum-to-100/Mathematica/sum-to-100-1.math
Normal file
2
Task/Sum-to-100/Mathematica/sum-to-100-1.math
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
operations = DeleteCases[Tuples[{"+", "-", ""}, 9], {x_, y__} /; x == "+"];
|
||||
sums = Map[StringJoin[Riffle[#, CharacterRange["1", "9"]]] &, operations];
|
||||
1
Task/Sum-to-100/Mathematica/sum-to-100-2.math
Normal file
1
Task/Sum-to-100/Mathematica/sum-to-100-2.math
Normal file
|
|
@ -0,0 +1 @@
|
|||
TableForm@Select[sums, ToExpression@# == 100 &]
|
||||
1
Task/Sum-to-100/Mathematica/sum-to-100-3.math
Normal file
1
Task/Sum-to-100/Mathematica/sum-to-100-3.math
Normal file
|
|
@ -0,0 +1 @@
|
|||
MaximalBy[Counts@ToExpression@sums, Identity]
|
||||
2
Task/Sum-to-100/Mathematica/sum-to-100-4.math
Normal file
2
Task/Sum-to-100/Mathematica/sum-to-100-4.math
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
pos = Cases[ToExpression@sums, _?Positive];
|
||||
n = 1; While[MemberQ[pos, n], ++n];
|
||||
1
Task/Sum-to-100/Mathematica/sum-to-100-5.math
Normal file
1
Task/Sum-to-100/Mathematica/sum-to-100-5.math
Normal file
|
|
@ -0,0 +1 @@
|
|||
{#, ToExpression@#}&/@TakeLargestBy[sums, ToExpression, 10]//TableForm
|
||||
138
Task/Sum-to-100/Modula-2/sum-to-100.mod2
Normal file
138
Task/Sum-to-100/Modula-2/sum-to-100.mod2
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
MODULE SumTo100;
|
||||
FROM FormatString IMPORT FormatString;
|
||||
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
|
||||
|
||||
PROCEDURE Evaluate(code : INTEGER) : INTEGER;
|
||||
VAR
|
||||
value,number,power,k : INTEGER;
|
||||
BEGIN
|
||||
value := 0;
|
||||
number := 0;
|
||||
power := 1;
|
||||
|
||||
FOR k:=9 TO 1 BY -1 DO
|
||||
number := power * k + number;
|
||||
IF code MOD 3 = 0 THEN
|
||||
(* ADD *)
|
||||
value := value + number;
|
||||
number := 0;
|
||||
power := 1
|
||||
ELSIF code MOD 3 = 1 THEN
|
||||
(* SUB *)
|
||||
value := value - number;
|
||||
number := 0;
|
||||
power := 1
|
||||
ELSE
|
||||
(* CAT *)
|
||||
power := power * 10
|
||||
END;
|
||||
code := code / 3
|
||||
END;
|
||||
|
||||
RETURN value
|
||||
END Evaluate;
|
||||
|
||||
PROCEDURE Print(code : INTEGER);
|
||||
VAR
|
||||
expr,buf : ARRAY[0..63] OF CHAR;
|
||||
a,b,k,p : INTEGER;
|
||||
BEGIN
|
||||
a := 19683;
|
||||
b := 6561;
|
||||
p := 0;
|
||||
|
||||
FOR k:=1 TO 9 DO
|
||||
IF (code MOD a) / b = 0 THEN
|
||||
IF k > 1 THEN
|
||||
expr[p] := '+';
|
||||
INC(p)
|
||||
END
|
||||
ELSIF (code MOD a) / b = 1 THEN
|
||||
expr[p] := '-';
|
||||
INC(p)
|
||||
END;
|
||||
|
||||
a := b;
|
||||
b := b / 3;
|
||||
expr[p] := CHR(k + 30H);
|
||||
INC(p)
|
||||
END;
|
||||
expr[p] := 0C;
|
||||
|
||||
FormatString("%9i = %s\n", buf, Evaluate(code), expr);
|
||||
WriteString(buf)
|
||||
END Print;
|
||||
|
||||
(* Main *)
|
||||
CONST nexpr = 13122;
|
||||
VAR
|
||||
i,j : INTEGER;
|
||||
best,nbest,test,ntest,limit : INTEGER;
|
||||
buf : ARRAY[0..63] OF CHAR;
|
||||
BEGIN
|
||||
WriteString("Show all solution that sum to 100");
|
||||
WriteLn;
|
||||
FOR i:=0 TO nexpr-1 DO
|
||||
IF Evaluate(i) = 100 THEN
|
||||
Print(i)
|
||||
END
|
||||
END;
|
||||
WriteLn;
|
||||
|
||||
WriteString("Show the sum that has the maximum number of solutions");
|
||||
WriteLn;
|
||||
nbest := -1;
|
||||
FOR i:=0 TO nexpr-1 DO
|
||||
test := Evaluate(i);
|
||||
IF test > 0 THEN
|
||||
ntest := 0;
|
||||
FOR j:=0 TO nexpr-1 DO
|
||||
IF Evaluate(j) = test THEN
|
||||
INC(ntest)
|
||||
END;
|
||||
IF ntest > nbest THEN
|
||||
best := test;
|
||||
nbest := ntest
|
||||
END
|
||||
END
|
||||
END
|
||||
END;
|
||||
FormatString("%i has %i solutions\n\n", buf, best, nbest);
|
||||
WriteString(buf);
|
||||
|
||||
WriteString("Show the lowest positive number that can't be expressed");
|
||||
WriteLn;
|
||||
FOR i:=0 TO 123456789 DO
|
||||
FOR j:=0 TO nexpr-1 DO
|
||||
IF i = Evaluate(j) THEN
|
||||
BREAK
|
||||
END
|
||||
END;
|
||||
IF i # Evaluate(j) THEN
|
||||
BREAK
|
||||
END
|
||||
END;
|
||||
FormatString("%i\n\n", buf, i);
|
||||
WriteString(buf);
|
||||
|
||||
WriteString("Show the ten highest numbers that can be expressed");
|
||||
WriteLn;
|
||||
limit := 123456789 + 1;
|
||||
FOR i:=1 TO 10 DO
|
||||
best := 0;
|
||||
FOR j:=0 TO nexpr-1 DO
|
||||
test := Evaluate(j);
|
||||
IF (test < limit) AND (test > best) THEN
|
||||
best := test
|
||||
END
|
||||
END;
|
||||
FOR j:=0 TO nexpr-1 DO
|
||||
IF Evaluate(j) = best THEN
|
||||
Print(j)
|
||||
END
|
||||
END;
|
||||
limit := best
|
||||
END;
|
||||
|
||||
ReadChar
|
||||
END SumTo100.
|
||||
42
Task/Sum-to-100/Nim/sum-to-100-1.nim
Normal file
42
Task/Sum-to-100/Nim/sum-to-100-1.nim
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import algorithm, parseutils, sequtils, strutils, tables
|
||||
|
||||
type Expression = string
|
||||
|
||||
proc buildExprs(start: Natural = 0): seq[Expression] =
|
||||
let item = if start == 0: "" else: $start
|
||||
if start == 9: return @[item]
|
||||
for expr in buildExprs(start + 1):
|
||||
result.add item & expr
|
||||
result.add item & '-' & expr
|
||||
if start != 0: result.add item & '+' & expr
|
||||
|
||||
proc evaluate(expr: Expression): int =
|
||||
var idx = 0
|
||||
var val: int
|
||||
while idx < expr.len:
|
||||
let n = expr.parseInt(val, idx)
|
||||
inc idx, n
|
||||
result += val
|
||||
|
||||
let exprs = buildExprs()
|
||||
var counts: CountTable[int]
|
||||
|
||||
echo "The solutions for 100 are:"
|
||||
for expr in exprs:
|
||||
let sum = evaluate(expr)
|
||||
if sum == 100: echo expr
|
||||
if sum > 0: counts.inc(sum)
|
||||
|
||||
let (n, count) = counts.largest()
|
||||
echo "\nThe maximum count of positive solutions is $1 for number $2.".format(count, n)
|
||||
|
||||
var s = 1
|
||||
while true:
|
||||
if s notin counts:
|
||||
echo "\nThe smallest number than cannot be expressed is: $1.".format(s)
|
||||
break
|
||||
inc s
|
||||
|
||||
echo "\nThe ten highest numbers than can be expressed are:"
|
||||
let numbers = sorted(toSeq(counts.keys), Descending)
|
||||
echo numbers[0..9].join(", ")
|
||||
76
Task/Sum-to-100/Nim/sum-to-100-2.nim
Normal file
76
Task/Sum-to-100/Nim/sum-to-100-2.nim
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import strutils
|
||||
|
||||
var
|
||||
ligne: string = ""
|
||||
sum: int
|
||||
opera: array[0..9, int] = [0,0,1,1,1,1,1,1,1,1]
|
||||
curseur: int = 9
|
||||
boucle: bool
|
||||
tot: array[1..123456789, int]
|
||||
pG: int
|
||||
plusGrandes: array[1..10, string]
|
||||
|
||||
let
|
||||
ope: array[0..3, string] = ["-",""," +"," -"]
|
||||
aAtteindre = 100
|
||||
|
||||
proc calcul(li: string): int =
|
||||
var liS: seq[string]
|
||||
liS = split(li," ")
|
||||
for i in liS:
|
||||
if i.len > 0: result += parseInt(i)
|
||||
|
||||
echo "Valeur à atteindre : ",aAtteindre
|
||||
|
||||
while opera[1]<2:
|
||||
ligne.add(ope[opera[1]])
|
||||
ligne.add("1")
|
||||
for i in 2..9:
|
||||
ligne.add(ope[opera[i]])
|
||||
ligne.add($i)
|
||||
sum = calcul(ligne)
|
||||
if sum == aAtteindre:
|
||||
stdout.write(ligne)
|
||||
echo " = ",sum
|
||||
if sum>0:
|
||||
tot[sum] += 1
|
||||
pG = 1
|
||||
while pG<10:
|
||||
if sum>calcul(plusGrandes[pG]):
|
||||
for k in countdown(10,pG+1):
|
||||
plusGrandes[k]=plusGrandes[k-1]
|
||||
plusGrandes[pG]=ligne
|
||||
pG = 11
|
||||
pG += 1
|
||||
ligne = ""
|
||||
boucle = true
|
||||
while boucle:
|
||||
opera[curseur] += 1
|
||||
if opera[curseur] == 4:
|
||||
opera[curseur]=1
|
||||
curseur -= 1
|
||||
else:
|
||||
curseur = 9
|
||||
boucle = false
|
||||
|
||||
echo "Valeur atteinte ",tot[aAtteindre]," fois."
|
||||
echo ""
|
||||
|
||||
var
|
||||
min0: int = 0
|
||||
max: int = 0
|
||||
valmax: int = 0
|
||||
|
||||
for i in 1..123456789:
|
||||
if tot[i]==0 and min0 == 0:
|
||||
min0 = i
|
||||
if tot[i]>max:
|
||||
max = tot[i]
|
||||
valmax = i
|
||||
|
||||
echo "Plus petite valeur ne pouvant pas être atteinte : ",min0
|
||||
echo "Valeur atteinte le plus souvent : ",valmax,", atteinte ",max," fois."
|
||||
echo ""
|
||||
echo "Plus grandes valeurs pouvant être atteintes :"
|
||||
for i in 1..10:
|
||||
echo calcul(plusGrandes[i])," = ",plusGrandes[i]
|
||||
126
Task/Sum-to-100/Pascal/sum-to-100.pas
Normal file
126
Task/Sum-to-100/Pascal/sum-to-100.pas
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
{ RossetaCode: Sum to 100, Pascal.
|
||||
|
||||
Find solutions to the "sum to one hundred" puzzle.
|
||||
|
||||
We don't use arrays, but recompute all values again and again.
|
||||
It is a little surprise that the time efficiency is quite acceptable. }
|
||||
|
||||
program sumto100;
|
||||
|
||||
const
|
||||
ADD = 0; SUB = 1; JOIN = 2; { opcodes inserted between digits }
|
||||
NEXPR = 13122; { the total number of expressions }
|
||||
var
|
||||
i, j: integer;
|
||||
loop: boolean;
|
||||
test, ntest, best, nbest, limit: integer;
|
||||
|
||||
function evaluate(code: integer): integer;
|
||||
var
|
||||
k: integer;
|
||||
value, number, power: integer;
|
||||
begin
|
||||
value := 0;
|
||||
number := 0;
|
||||
power := 1;
|
||||
for k := 9 downto 1 do
|
||||
begin
|
||||
number := power * k + number;
|
||||
case code mod 3 of
|
||||
ADD: begin value := value + number; number := 0; power := 1; end;
|
||||
SUB: begin value := value - number; number := 0; power := 1; end;
|
||||
JOIN: power := power * 10
|
||||
end;
|
||||
code := code div 3
|
||||
end;
|
||||
evaluate := value
|
||||
end;
|
||||
|
||||
procedure print(code: integer);
|
||||
var
|
||||
k: integer;
|
||||
a, b: integer;
|
||||
begin
|
||||
a := 19683;
|
||||
b := 6561;
|
||||
write( evaluate(code):9 );
|
||||
write(' = ');
|
||||
for k := 1 to 9 do
|
||||
begin
|
||||
case ((code mod a) div b) of
|
||||
ADD: if k > 1 then write('+');
|
||||
SUB: { always } write('-');
|
||||
end;
|
||||
a := b;
|
||||
b := b div 3;
|
||||
write( k:1 )
|
||||
end;
|
||||
writeln
|
||||
end;
|
||||
|
||||
begin
|
||||
writeln;
|
||||
writeln('Show all solutions that sum to 100');
|
||||
writeln;
|
||||
for i := 0 to NEXPR - 1 do
|
||||
if evaluate(i) = 100 then
|
||||
print(i);
|
||||
|
||||
writeln;
|
||||
writeln('Show the sum that has the maximum number of solutions');
|
||||
writeln;
|
||||
nbest := (-1);
|
||||
for i := 0 to NEXPR - 1 do
|
||||
begin
|
||||
test := evaluate(i);
|
||||
if test > 0 then
|
||||
begin
|
||||
ntest := 0;
|
||||
for j := 0 to NEXPR - 1 do
|
||||
if evaluate(j) = test then
|
||||
ntest := ntest + 1;
|
||||
if ntest > nbest then
|
||||
begin
|
||||
best := test;
|
||||
nbest := ntest;
|
||||
end
|
||||
end
|
||||
end;
|
||||
writeln(best, ' has ', nbest, ' solutions');
|
||||
|
||||
writeln;
|
||||
writeln('Show the lowest positive number that can''t be expressed');
|
||||
writeln;
|
||||
i := 0;
|
||||
loop := TRUE;
|
||||
while (i <= 123456789) and loop do
|
||||
begin
|
||||
j := 0;
|
||||
while (j < NEXPR - 1) and (i <> evaluate(j)) do
|
||||
j := j + 1;
|
||||
if i <> evaluate(j) then
|
||||
loop := FALSE
|
||||
else
|
||||
i := i + 1;
|
||||
end;
|
||||
writeln(i);
|
||||
|
||||
writeln;
|
||||
writeln('Show the ten highest numbers that can be expressed');
|
||||
writeln;
|
||||
limit := 123456789 + 1;
|
||||
for i := 1 to 10 do
|
||||
begin
|
||||
best := 0;
|
||||
for j := 0 to NEXPR - 1 do
|
||||
begin
|
||||
test := evaluate(j);
|
||||
if (test < limit) and (test > best) then
|
||||
best := test;
|
||||
end;
|
||||
for j := 0 to NEXPR - 1 do
|
||||
if evaluate(j) = best then
|
||||
print(j);
|
||||
limit := best;
|
||||
end
|
||||
end.
|
||||
62
Task/Sum-to-100/Perl/sum-to-100-1.pl
Normal file
62
Task/Sum-to-100/Perl/sum-to-100-1.pl
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/perl
|
||||
use warnings;
|
||||
use strict;
|
||||
use feature qw{ say };
|
||||
|
||||
my $string = '123456789';
|
||||
my $length = length $string;
|
||||
my @possible_ops = ("" , '+', '-');
|
||||
|
||||
{
|
||||
my @ops;
|
||||
sub Next {
|
||||
return @ops = (0) x ($length) unless @ops;
|
||||
|
||||
my $i = 0;
|
||||
while ($i < $length) {
|
||||
if ($ops[$i]++ > $#possible_ops - 1) {
|
||||
$ops[$i++] = 0;
|
||||
next
|
||||
}
|
||||
# + before the first number
|
||||
next if 0 == $i && '+' eq $possible_ops[ $ops[0] ];
|
||||
|
||||
return @ops
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
sub evaluate {
|
||||
my ($expression) = @_;
|
||||
my $sum;
|
||||
$sum += $_ for $expression =~ /([-+]?[0-9]+)/g;
|
||||
return $sum
|
||||
}
|
||||
|
||||
my %count = ( my $max_count = 0 => 0 );
|
||||
|
||||
say 'Show all solutions that sum to 100';
|
||||
|
||||
while (my @ops = Next()) {
|
||||
my $expression = "";
|
||||
for my $i (0 .. $length - 1) {
|
||||
$expression .= $possible_ops[ $ops[$i] ];
|
||||
$expression .= substr $string, $i, 1;
|
||||
}
|
||||
my $sum = evaluate($expression);
|
||||
++$count{$sum};
|
||||
$max_count = $sum if $count{$sum} > $count{$max_count};
|
||||
say $expression if 100 == $sum;
|
||||
}
|
||||
|
||||
say 'Show the sum that has the maximum number of solutions';
|
||||
say "sum: $max_count; solutions: $count{$max_count}";
|
||||
|
||||
my $n = 1;
|
||||
++$n until ! exists $count{$n};
|
||||
say "Show the lowest positive sum that can't be expressed";
|
||||
say $n;
|
||||
|
||||
say 'Show the ten highest numbers that can be expressed';
|
||||
say for (sort { $b <=> $a } keys %count)[0 .. 9];
|
||||
1
Task/Sum-to-100/Perl/sum-to-100-2.pl
Normal file
1
Task/Sum-to-100/Perl/sum-to-100-2.pl
Normal file
|
|
@ -0,0 +1 @@
|
|||
perl -E "say for grep{eval $_ == 100} glob '{-,}'.join '{+,-,}',1..9"
|
||||
1
Task/Sum-to-100/Perl/sum-to-100-3.pl
Normal file
1
Task/Sum-to-100/Perl/sum-to-100-3.pl
Normal file
|
|
@ -0,0 +1 @@
|
|||
perl -MList::Util="first" -E "@c[0..10**6]=(0..10**6);say for grep{$e=eval;$c[$e]=undef if $e>=0;$h{$e}++;eval $_==100}glob'{-,}'.join'{+,-,}',1..9;END{say for(sort{$h{$b}<=>$h{$a}}grep{$_>=0}keys %h)[0],first{defined $_}@c;say for(sort{$b<=>$a}grep{$_>0}keys %h)[0..9]}"
|
||||
86
Task/Sum-to-100/Phix/sum-to-100.phix
Normal file
86
Task/Sum-to-100/Phix/sum-to-100.phix
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #000000;">javascript_semantics</span>
|
||||
<span style="color: #008080;">enum</span> <span style="color: #000000;">SUB</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">NOP</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ADD</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">evaluate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tmp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ADD</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">NOP</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">tmp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tmp</span><span style="color: #0000FF;">*</span><span style="color: #000000;">10</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">op</span><span style="color: #0000FF;">*</span><span style="color: #000000;">tmp</span>
|
||||
<span style="color: #000000;">tmp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
|
||||
<span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">op</span><span style="color: #0000FF;">*</span><span style="color: #000000;">tmp</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">NOP</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">','</span><span style="color: #0000FF;">-</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'0'</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s = %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">evaluate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">-- Logically this intersperses -/nop/+ between each digit, but you do not actually need the digit.</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">SUB</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (==> ..nop+add*8)</span>
|
||||
|
||||
<span style="color: #004080;">bool</span> <span style="color: #000000;">done</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">maxl</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">maxr</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #000000;">done</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">evaluate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">solns</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?{}:</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">getd_by_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">)))</span>
|
||||
<span style="color: #000000;">solns</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solns</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solns</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #000000;">maxl</span><span style="color: #0000FF;"><</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solns</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">maxl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solns</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">maxr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">NOP</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">done</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
|
||||
<span style="color: #008080;">exit</span>
|
||||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">ADD</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">exit</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">SUB</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d solutions considered (dictionary size: %d)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">count</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">dict_size</span><span style="color: #0000FF;">()})</span>
|
||||
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s100</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">100</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"There are %d sums to 100:\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s100</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #7060A8;">papply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">show</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"The positive sum of %d has the maximum number of solutions: %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">maxr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">maxl</span><span style="color: #0000FF;">})</span>
|
||||
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">prev</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">missing</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">key</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000080;font-style:italic;">/*data*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000080;font-style:italic;">/*pkey*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000080;font-style:italic;">/*user_data=-2*/</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">key</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">prev</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">prev</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">key</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
<span style="color: #7060A8;">traverse_dict_partial_key</span><span style="color: #0000FF;">(</span><span style="color: #000000;">missing</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"The lowest positive sum that cannot be expressed: %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">prev</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
|
||||
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">highest</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">top10</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">key</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000080;font-style:italic;">/*data*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000080;font-style:italic;">/*user_data*/</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">highest</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">key</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">highest</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">10</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
<span style="color: #000080;font-style:italic;">--DEV named params on builtins need pre-loading...:
|
||||
--traverse_dict(top10,rev:=1)</span>
|
||||
<span style="color: #7060A8;">traverse_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">top10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"The 10 highest sums: %v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">highest</span><span style="color: #0000FF;">})</span>
|
||||
<!--
|
||||
11
Task/Sum-to-100/Picat/sum-to-100.picat
Normal file
11
Task/Sum-to-100/Picat/sum-to-100.picat
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
main =>
|
||||
L = "23456789",
|
||||
gen(L,Str),
|
||||
Exp = parse_term(['1'|Str]),
|
||||
Exp =:= 100,
|
||||
println(['1'|Str]).
|
||||
|
||||
gen(L@[_],Str) => Str = L.
|
||||
gen([D|Ds],Str) ?=> Str = [D|StrR], gen(Ds,StrR). % no operator
|
||||
gen([D|Ds],Str) ?=> Str = ['+',D|StrR], gen(Ds,StrR). % insert +
|
||||
gen([D|Ds],Str) => Str = ['-',D|StrR], gen(Ds,StrR). % insert -
|
||||
73
Task/Sum-to-100/PureBasic/sum-to-100.basic
Normal file
73
Task/Sum-to-100/PureBasic/sum-to-100.basic
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#START=6561
|
||||
#STOPP=19682
|
||||
#SUMME=100
|
||||
#BASIS="123456789"
|
||||
|
||||
Structure TSumTerm
|
||||
sum.i
|
||||
ter.s
|
||||
EndStructure
|
||||
|
||||
NewList Solutions.TSumTerm()
|
||||
NewMap SolCount.i()
|
||||
Dim op.s{1}(8)
|
||||
Dim b.s{1}(8)
|
||||
PokeS(@b(),#BASIS)
|
||||
|
||||
Procedure StripTerm(*p_Term)
|
||||
If PeekS(*p_Term,1)="+" : PokeC(*p_Term,' ') : EndIf
|
||||
EndProcedure
|
||||
|
||||
Procedure.s Triadisch(v)
|
||||
While v : r$=Str(v%3)+r$ : v/3 : Wend
|
||||
ProcedureReturn r$
|
||||
EndProcedure
|
||||
|
||||
Procedure.i Calc(t$)
|
||||
While Len(t$)
|
||||
x=Val(t$) : r+x
|
||||
If x<0 : s$=Str(x) : Else : s$="+"+Str(x) : EndIf
|
||||
t$=RemoveString(t$,s$,#PB_String_NoCase,1,1)
|
||||
Wend
|
||||
ProcedureReturn r
|
||||
EndProcedure
|
||||
|
||||
For n=#START To #STOPP
|
||||
PokeS(@op(),Triadisch(n))
|
||||
Term$=""
|
||||
For i=0 To 8
|
||||
Select op(i)
|
||||
Case "0" : Term$+ b(i)
|
||||
Case "1" : Term$+"+"+b(i)
|
||||
Case "2" : Term$+"-"+b(i)
|
||||
EndSelect
|
||||
Next
|
||||
AddElement(Solutions()) : Solutions()\sum=Calc(Term$) : StripTerm(@Term$) : Solutions()\ter=Term$
|
||||
Next
|
||||
SortStructuredList(Solutions(),#PB_Sort_Ascending,OffsetOf(TSumTerm\sum),TypeOf(TSumTerm\sum))
|
||||
|
||||
If OpenConsole()
|
||||
PrintN("Show all solutions that sum to 100:")
|
||||
ForEach Solutions()
|
||||
If Solutions()\sum=#SUMME : PrintN(#TAB$+Solutions()\ter) : EndIf
|
||||
SolCount(Str(Solutions()\sum))+1
|
||||
Next
|
||||
ForEach SolCount()
|
||||
If SolCount()>MaxCount : MaxCount=SolCount() : MaxVal$=MapKey(SolCount()) : EndIf
|
||||
Next
|
||||
PrintN("Show the positve sum that has the maximum number of solutions:")
|
||||
PrintN(#TAB$+MaxVal$+" has "+Str(MaxCount)+" solutions")
|
||||
If LastElement(Solutions())
|
||||
MaxVal=Solutions()\sum
|
||||
PrintN("Show the lowest positive number that can't be expressed:")
|
||||
For i=1 To MaxVal
|
||||
If SolCount(Str(i))=0 : PrintN(#TAB$+Str(i)) : Break : EndIf
|
||||
Next
|
||||
PrintN("Show the 10 highest numbers that can be expressed:")
|
||||
For i=1 To 10
|
||||
PrintN(#TAB$+LSet(Str(Solutions()\sum),9)+" = "+Solutions()\ter)
|
||||
If Not PreviousElement(Solutions()) : Break : EndIf
|
||||
Next
|
||||
EndIf
|
||||
Input()
|
||||
EndIf
|
||||
51
Task/Sum-to-100/Python/sum-to-100-1.py
Normal file
51
Task/Sum-to-100/Python/sum-to-100-1.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
from itertools import product, islice
|
||||
|
||||
|
||||
def expr(p):
|
||||
return "{}1{}2{}3{}4{}5{}6{}7{}8{}9".format(*p)
|
||||
|
||||
|
||||
def gen_expr():
|
||||
op = ['+', '-', '']
|
||||
return [expr(p) for p in product(op, repeat=9) if p[0] != '+']
|
||||
|
||||
|
||||
def all_exprs():
|
||||
values = {}
|
||||
for expr in gen_expr():
|
||||
val = eval(expr)
|
||||
if val not in values:
|
||||
values[val] = 1
|
||||
else:
|
||||
values[val] += 1
|
||||
return values
|
||||
|
||||
|
||||
def sum_to(val):
|
||||
for s in filter(lambda x: x[0] == val, map(lambda x: (eval(x), x), gen_expr())):
|
||||
print(s)
|
||||
|
||||
|
||||
def max_solve():
|
||||
print("Sum {} has the maximum number of solutions: {}".
|
||||
format(*max(all_exprs().items(), key=lambda x: x[1])))
|
||||
|
||||
|
||||
def min_solve():
|
||||
values = all_exprs()
|
||||
for i in range(123456789):
|
||||
if i not in values:
|
||||
print("Lowest positive sum that can't be expressed: {}".format(i))
|
||||
return
|
||||
|
||||
|
||||
def highest_sums(n=10):
|
||||
sums = map(lambda x: x[0],
|
||||
islice(sorted(all_exprs().items(), key=lambda x: x[0], reverse=True), n))
|
||||
print("Highest Sums: {}".format(list(sums)))
|
||||
|
||||
|
||||
sum_to(100)
|
||||
max_solve()
|
||||
min_solve()
|
||||
highest_sums()
|
||||
29
Task/Sum-to-100/Python/sum-to-100-2.py
Normal file
29
Task/Sum-to-100/Python/sum-to-100-2.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import itertools
|
||||
from collections import defaultdict, Counter
|
||||
|
||||
s = "123456789"
|
||||
h = defaultdict(list)
|
||||
for v in itertools.product(["+", "-", ""], repeat=9):
|
||||
if v[0] != "+":
|
||||
e = "".join("".join(u) for u in zip(v, s))
|
||||
h[eval(e)].append(e)
|
||||
|
||||
print("Solutions for 100")
|
||||
for e in h[100]:
|
||||
print(e)
|
||||
|
||||
c = Counter({k: len(v) for k, v in h.items() if k >= 0})
|
||||
|
||||
k, m = c.most_common(1)[0]
|
||||
print("Maximum number of solutions for %d (%d solutions)" % (k, m))
|
||||
|
||||
v = sorted(c.keys())
|
||||
|
||||
for i in range(v[-1]):
|
||||
if i not in c:
|
||||
print("Lowest impossible sum: %d" % i)
|
||||
break
|
||||
|
||||
print("Ten highest sums")
|
||||
for k in reversed(v[-10:]):
|
||||
print(k)
|
||||
51
Task/Sum-to-100/REXX/sum-to-100.rexx
Normal file
51
Task/Sum-to-100/REXX/sum-to-100.rexx
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*REXX pgm solves a puzzle: using the string 123456789, insert - or + to sum to 100*/
|
||||
parse arg LO HI . /*obtain optional arguments from the CL*/
|
||||
if LO=='' | LO=="," then LO= 100 /*Not specified? Then use the default.*/
|
||||
if HI=='' | HI=="," then HI= LO /* " " " " " " */
|
||||
if LO==00 then HI= 123456789 /*LOW specified as zero with leading 0.*/
|
||||
ops= '+-'; L= length(ops) + 1 /*define operators (and their length). */
|
||||
@.=; do i=1 for L-1; @.i= substr(ops,i,1) /* " some handy-dandy REXX literals*/
|
||||
end /*i*/ /* " individual operators for speed*/
|
||||
mx= 0; mn= 999999 /*initialize the minimums and maximums.*/
|
||||
mxL=; mnL=; do j=LO to HI until LO==00 & mn==0 /*solve with range of sums*/
|
||||
z= ???(j) /*find # solutions for J. */
|
||||
if z> mx then mxL= /*is this a new maximum ? */
|
||||
if z>=mx then do; mxL=mxL j; mx=z; end /*remember this new max. */
|
||||
if z< mn then mnL= /*is this a new minimum ? */
|
||||
if z<=mn then do; mnL=mnL j; mn=z; end /*remember this new min. */
|
||||
end /*j*/
|
||||
if LO==HI then exit 0 /*don't display max&min ? */
|
||||
@@= 'number of solutions: '; say
|
||||
_= words(mxL); say 'sum's(_) "of" mxL ' 's(_,"have",'has') 'the maximum' @@ mx
|
||||
_= words(mnL); say 'sum's(_) "of" mnL ' 's(_,"have",'has') 'the minimum' @@ mn
|
||||
exit 0 /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
s: if arg(1)==1 then return arg(3); return word( arg(2) "s",1) /*simple pluralizer*/
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
???: parse arg answer; #= 0 /*obtain the answer (sum) to the puzzle*/
|
||||
do a=L-1 for 2; aa= @.a'1' /*choose one of - or nothing. */
|
||||
do b=1 for L; bb= aa || @.b'2' /* " " " - +, or abutment.*/
|
||||
do c=1 for L; cc= bb || @.c'3' /* " " " " " " " */
|
||||
do d=1 for L; dd= cc || @.d'4' /* " " " " " " " */
|
||||
do e=1 for L; ee= dd || @.e'5' /* " " " " " " " */
|
||||
do f=1 for L; ff= ee || @.f'6' /* " " " " " " " */
|
||||
do g=1 for L; gg= ff || @.g'7' /* " " " " " " " */
|
||||
do h=1 for L; hh= gg || @.h'8' /* " " " " " " " */
|
||||
do i=1 for L; ii= hh || @.i'9' /* " " " " " " " */
|
||||
interpret '$=' ii /*calculate the sum of modified string.*/
|
||||
if $\==answer then iterate /*Is sum not equal to answer? Then skip*/
|
||||
#= # + 1; if LO==HI then say 'solution: ' $ " ◄───► " ii
|
||||
end /*i*/ /* */
|
||||
end /*h*/ /* d */
|
||||
end /*g*/ /* d */
|
||||
end /*f*/ /* eeeee n nnnn dddddd sssss */
|
||||
end /*e*/ /* e e nn n d d s */
|
||||
end /*d*/ /* eeeeeee n n d d sssss */
|
||||
end /*c*/ /* e n n d d s */
|
||||
end /*b*/ /* eeeee n n ddddd sssss */
|
||||
end /*a*/ /* */
|
||||
y= # /* [↓] adjust the number of solutions?*/
|
||||
if y==0 then y= 'no' /* [↓] left justify plural of solution*/
|
||||
if LO\==00 then say right(y, 9) 'solution's(#, , " ") 'found for' ,
|
||||
right(j, length(HI) ) left('', #, "─")
|
||||
return # /*return the number of solutions found.*/
|
||||
67
Task/Sum-to-100/Racket/sum-to-100.rkt
Normal file
67
Task/Sum-to-100/Racket/sum-to-100.rkt
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#lang racket
|
||||
|
||||
(define list-partitions
|
||||
(match-lambda
|
||||
[(list) (list null)]
|
||||
[(and L (list _)) (list (list L))]
|
||||
[(list L ...)
|
||||
(for*/list
|
||||
((i (in-range 1 (add1 (length L))))
|
||||
(r (in-list (list-partitions (drop L i)))))
|
||||
(cons (take L i) r))]))
|
||||
|
||||
(define digits->number (curry foldl (λ (dgt acc) (+ (* 10 acc) dgt)) 0))
|
||||
|
||||
(define partition-digits-to-numbers
|
||||
(let ((memo (make-hash)))
|
||||
(λ (dgts)
|
||||
(hash-ref! memo dgts
|
||||
(λ ()
|
||||
(map (λ (p) (map digits->number p))
|
||||
(list-partitions dgts)))))))
|
||||
|
||||
(define (fold-sum-to-ns digits kons k0)
|
||||
(define (get-solutions nmbrs acc chain k)
|
||||
(match nmbrs
|
||||
[(list)
|
||||
(kons (cons acc (let ((niahc (reverse chain)))
|
||||
(if (eq? '+ (car niahc)) (cdr niahc) niahc)))
|
||||
k)]
|
||||
[(cons a d)
|
||||
(get-solutions d (- acc a) (list* a '- chain)
|
||||
(get-solutions d (+ acc a) (list* a '+ chain) k))]))
|
||||
(foldl (λ (nmbrs k) (get-solutions nmbrs 0 null k)) k0 (partition-digits-to-numbers digits)))
|
||||
|
||||
(define sum-to-ns/hash-promise
|
||||
(delay (fold-sum-to-ns
|
||||
'(1 2 3 4 5 6 7 8 9)
|
||||
(λ (a.s d) (hash-update d (car a.s) (λ (x) (cons (cdr a.s) x)) list))
|
||||
(hash))))
|
||||
|
||||
(module+ main
|
||||
(define S (force sum-to-ns/hash-promise))
|
||||
(displayln "Show all solutions that sum to 100")
|
||||
(pretty-print (hash-ref S 100))
|
||||
|
||||
(displayln "Show the sum that has the maximum number of solutions (from zero to infinity*)")
|
||||
(let-values (([k-max v-max]
|
||||
(for/fold ((k-max #f) (v-max 0))
|
||||
(([k v] (in-hash S)) #:when (> (length v) v-max))
|
||||
(values k (length v)))))
|
||||
(printf "~a has ~a solutions~%" k-max v-max))
|
||||
|
||||
(displayln "Show the lowest positive sum that can't be expressed (has no solutions),
|
||||
using the rules for this task")
|
||||
(for/first ((n (in-range 1 (add1 123456789))) #:unless (hash-has-key? S n)) n)
|
||||
|
||||
(displayln "Show the ten highest numbers that can be expressed using the rules for this task")
|
||||
(take (sort (hash-keys S) >) 10))
|
||||
|
||||
(module+ test
|
||||
(require rackunit)
|
||||
(check-equal? (list-partitions null) '(()))
|
||||
(check-equal? (list-partitions '(1)) '(((1))))
|
||||
(check-equal? (list-partitions '(1 2)) '(((1) (2)) ((1 2))))
|
||||
(check-equal? (partition-digits-to-numbers '()) '(()))
|
||||
(check-equal? (partition-digits-to-numbers '(1)) '((1)))
|
||||
(check-equal? (partition-digits-to-numbers '(1 2)) '((1 2) (12))))
|
||||
19
Task/Sum-to-100/Raku/sum-to-100.raku
Normal file
19
Task/Sum-to-100/Raku/sum-to-100.raku
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
my $sum = 100;
|
||||
my $N = 10;
|
||||
my @ops = ['-', ''], |( [' + ', ' - ', ''] xx 8 );
|
||||
my @str = [X~] map { .Slip }, ( @ops Z 1..9 );
|
||||
my %sol = @str.classify: *.subst( ' - ', ' -', :g )\
|
||||
.subst( ' + ', ' ', :g ).words.sum;
|
||||
|
||||
my %count.push: %sol.map({ .value.elems => .key });
|
||||
|
||||
my $max-solutions = %count.max( + *.key );
|
||||
my $first-unsolvable = first { %sol{$_} :!exists }, 1..*;
|
||||
sub n-largest-sums (Int $n) { %sol.sort(-*.key)[^$n].fmt: "%8s => %s\n" }
|
||||
|
||||
given %sol{$sum}:p {
|
||||
say "{.value.elems} solutions for sum {.key}:";
|
||||
say " $_" for .value.list;
|
||||
}
|
||||
|
||||
.say for :$max-solutions, :$first-unsolvable, "$N largest sums:", n-largest-sums($N);
|
||||
17
Task/Sum-to-100/Ruby/sum-to-100.rb
Normal file
17
Task/Sum-to-100/Ruby/sum-to-100.rb
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
digits = ("1".."9").to_a
|
||||
|
||||
ar = ["+", "-", ""].repeated_permutation(digits.size).filter_map do |op_perm|
|
||||
str = op_perm.zip(digits).join
|
||||
str unless str.start_with?("+")
|
||||
end
|
||||
res = ar.group_by{|str| eval(str)}
|
||||
|
||||
puts res[100] , ""
|
||||
|
||||
sum, solutions = res.max_by{|k,v| v.size}
|
||||
puts "#{sum} has #{solutions.size} solutions.", ""
|
||||
|
||||
no_solution = (1..).find{|n| res[n] == nil}
|
||||
puts "#{no_solution} is the lowest positive number without a solution.", ""
|
||||
|
||||
puts res.max(10).map{|pair| pair.join(": ")}
|
||||
34
Task/Sum-to-100/Scala/sum-to-100.scala
Normal file
34
Task/Sum-to-100/Scala/sum-to-100.scala
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
object SumTo100 {
|
||||
def main(args: Array[String]): Unit = {
|
||||
val exps = expressions(9).map(str => (str, eval(str)))
|
||||
val sums = exps.map(_._2).sortWith(_>_)
|
||||
|
||||
val s1 = exps.filter(_._2 == 100)
|
||||
val s2 = sums.distinct.map(s => (s, sums.count(_ == s))).maxBy(_._2)
|
||||
val s3 = sums.distinct.reverse.filter(_>0).zipWithIndex.dropWhile{case (n, i) => n == i + 1}.head._2 + 1
|
||||
val s4 = sums.distinct.take(10)
|
||||
|
||||
println(s"""All ${s1.size} solutions that sum to 100:
|
||||
|${s1.sortBy(_._1.length).map(p => s"${p._2} = ${p._1.tail}").mkString("\n")}
|
||||
|
|
||||
|Most common sum: ${s2._1} (${s2._2})
|
||||
|Lowest unreachable sum: $s3
|
||||
|Highest 10 sums: ${s4.mkString(", ")}""".stripMargin)
|
||||
}
|
||||
|
||||
def expressions(l: Int): LazyList[String] = configurations(l).map(p => p.zipWithIndex.map{case (op, n) => s"${opChar(op)}${n + 1}"}.mkString)
|
||||
def configurations(l: Int): LazyList[Vector[Int]] = LazyList.range(0, math.pow(3, l).toInt).map(config(l)).filter(_.head != 0)
|
||||
def config(l: Int)(num: Int): Vector[Int] = Iterator.iterate((num%3, num/3)){case (_, n) => (n%3, n/3)}.map(_._1 - 1).take(l).toVector
|
||||
|
||||
def eval(exp: String): Int = (exp.headOption, exp.tail.takeWhile(_.isDigit), exp.tail.dropWhile(_.isDigit)) match{
|
||||
case (Some(op), n, str) => doOp(op, n.toInt) + eval(str)
|
||||
case _ => 0
|
||||
}
|
||||
|
||||
def doOp(sel: Char, n: Int): Int = if(sel == '-') -n else n
|
||||
def opChar(sel: Int): String = sel match{
|
||||
case -1 => "-"
|
||||
case 1 => "+"
|
||||
case _ => ""
|
||||
}
|
||||
}
|
||||
40
Task/Sum-to-100/Sidef/sum-to-100.sidef
Normal file
40
Task/Sum-to-100/Sidef/sum-to-100.sidef
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
func gen_expr() is cached {
|
||||
var x = ['-', '']
|
||||
var y = ['+', '-', '']
|
||||
|
||||
gather {
|
||||
cartesian([x,y,y,y,y,y,y,y,y], {|a,b,c,d,e,f,g,h,i|
|
||||
take("#{a}1#{b}2#{c}3#{d}4#{e}5#{f}6#{g}7#{h}8#{i}9")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func eval_expr(expr) is cached {
|
||||
expr.scan(/([-+]?\d+)/).sum_by { Num(_) }
|
||||
}
|
||||
|
||||
func sum_to(val) {
|
||||
gen_expr().grep { eval_expr(_) == val }
|
||||
}
|
||||
|
||||
func max_solve() {
|
||||
gen_expr().grep { eval_expr(_) >= 0 } \
|
||||
.group_by { eval_expr(_) } \
|
||||
.max_by {|_,v| v.len }
|
||||
}
|
||||
|
||||
func min_solve() {
|
||||
var h = gen_expr().group_by { eval_expr(_) }
|
||||
for i in (0..Inf) { h.exists(i) || return i }
|
||||
}
|
||||
|
||||
func highest_sums(n=10) {
|
||||
gen_expr().map { eval_expr(_) }.uniq.sort.reverse.first(n)
|
||||
}
|
||||
|
||||
sum_to(100).each { say "100 = #{_}" }
|
||||
|
||||
var (n, solutions) = max_solve()...
|
||||
say "Sum of #{n} has the maximum number of solutions: #{solutions.len}"
|
||||
say "Lowest positive sum that can't be expressed : #{min_solve()}"
|
||||
say "Highest sums: #{highest_sums()}"
|
||||
37
Task/Sum-to-100/Tcl/sum-to-100.tcl
Normal file
37
Task/Sum-to-100/Tcl/sum-to-100.tcl
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
proc sum_to_100 {} {
|
||||
for {set i 0} {$i <= 13121} {incr i} {
|
||||
set i3 [format %09d [dec2base 3 $i]]
|
||||
set form ""
|
||||
set subs {"" - +}
|
||||
foreach a [split $i3 ""] b [split 123456789 ""] {
|
||||
append form [lindex $subs $a] $b
|
||||
}
|
||||
lappend R([expr $form]) $form
|
||||
}
|
||||
puts "solutions for sum=100:\n[join [lsort $R(100)] \n]"
|
||||
set max -1
|
||||
foreach key [array names R] {
|
||||
if {[llength $R($key)] > $max} {
|
||||
set max [llength $R($key)]
|
||||
set maxkey $key
|
||||
}
|
||||
}
|
||||
puts "max solutions: $max for $maxkey"
|
||||
for {set i 0} {$i <= 123456789} {incr i} {
|
||||
if ![info exists R($i)] {
|
||||
puts "first unsolvable: $i"
|
||||
break
|
||||
}
|
||||
}
|
||||
puts "highest 10:\n[lrange [lsort -integer -decr [array names R]] 0 9]"
|
||||
}
|
||||
proc dec2base {base dec} {
|
||||
set res ""
|
||||
while {$dec > 0} {
|
||||
set res [expr $dec%$base]$res
|
||||
set dec [expr $dec/$base]
|
||||
}
|
||||
if {$res eq ""} {set res 0}
|
||||
return $res
|
||||
}
|
||||
sum_to_100
|
||||
103
Task/Sum-to-100/Visual-Basic-.NET/sum-to-100.vb
Normal file
103
Task/Sum-to-100/Visual-Basic-.NET/sum-to-100.vb
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
' Recursively iterates (increments) iteration array, returns -1 when out of "digits".
|
||||
Function plusOne(iAry() As Integer, spot As Integer) As Integer
|
||||
Dim spotLim As Integer = If(spot = 0, 1, 2) ' The first "digit" has a lower limit.
|
||||
If iAry(spot) = spotLim Then ' Check if spot has reached limit
|
||||
If spot = 0 Then Return -1 ' No previous spot to increment, so indicate completed.
|
||||
iAry(spot) = 0 ' Reset current spot, and
|
||||
Return plusOne(iAry, spot - 1) ' Increment previous spot.
|
||||
Else
|
||||
iAry(spot) += 1 ' Increment current spot.
|
||||
End If
|
||||
Return spot
|
||||
End Function
|
||||
|
||||
' Returns string sequence of operations from iAry and terms string
|
||||
Function generate(iAry() As Integer, terms As String) As String
|
||||
Dim operations As String() = {"", "-", "+"} ' Possible operations.
|
||||
generate = ""
|
||||
For i As Integer = 0 To iAry.Count - 1
|
||||
generate &= operations(iAry(i)) & Mid(terms, i + 1, 1).ToString()
|
||||
Next
|
||||
End Function
|
||||
|
||||
' Returns evaluation of string sequence
|
||||
Function eval(sequence As String) As Integer
|
||||
eval = 0
|
||||
Dim term As Integer = 0, operation As Integer = 1
|
||||
For Each ch As Char In sequence
|
||||
Select Case ch
|
||||
Case "-", "+" ' New operation detected, apply previous operation to term,
|
||||
eval += If(operation = 0, -term, term) : term = 0 ' and reset term.
|
||||
operation = If(ch = "-", 0, 1) ' Note next operation.
|
||||
Case Else ' Digit detected, increase term.
|
||||
term = term * 10 + Val(ch)
|
||||
End Select
|
||||
Next
|
||||
eval += If(operation = 0, -term, term) ' Apply final term.
|
||||
End Function
|
||||
|
||||
' Sorts a pair of List(Of Integer) by the first
|
||||
Sub reSort(ByRef first As List(Of Integer), ByRef second As List(Of Integer))
|
||||
Dim lou As New List(Of ULong) ' Temporary list of ULong for sorting.
|
||||
For i As Integer = 0 To first.Count - 1
|
||||
lou.Add((CULng(first(i)) << 32) + second(i)) ' "Pack" list items.
|
||||
Next
|
||||
lou.Sort()
|
||||
For k As Integer = 0 To first.Count - 1
|
||||
first(k) = lou(k) >> 32 ' "Unpack" first list item.
|
||||
second(k) = lou(k) And &H7FFFFFFF ' "Unpack" second list item.
|
||||
Next
|
||||
End Sub
|
||||
|
||||
' Returns first result not in sequence, assumes passed list is sorted before call,
|
||||
' uses binary search algo.
|
||||
Function firstMiss(loi As List(Of Integer))
|
||||
Dim low As Integer = 0, high As Integer = loi.Count - 1, middle = (low + high) \ 2
|
||||
Do
|
||||
If loi(middle) = middle Then low = middle + 1 Else high = middle - 1
|
||||
middle = (low + high) \ 2
|
||||
Loop Until high <= low
|
||||
Return middle + If(loi(middle) = middle, 1, 0)
|
||||
End Function
|
||||
|
||||
' Iterates through all possible operations,
|
||||
' uses a pair of List (of Integer) to tabulate solutions.
|
||||
Sub Solve100(Optional terms As String = "123456789",
|
||||
Optional targSum As Integer = 100,
|
||||
Optional highNums As Integer = 10)
|
||||
Dim lastDig As Integer = Len(terms) - 1 ' The final "digit".
|
||||
Dim iAry() As Integer = New Integer(lastDig) {} ' Iterations array.
|
||||
Dim seq As String ' Sequence of numbers and operations.
|
||||
Dim sVal As Integer ' Sequence value.
|
||||
Dim sCnt As Integer = 1 ' Solution count (targSum).
|
||||
Dim res As New List(Of Integer) ' List of results.
|
||||
Dim tally As New List(Of Integer) ' Tally of results.
|
||||
Console.WriteLine("List of solutions that evaluate to 100:")
|
||||
Do ' Tabulate results until digits are exhausted.
|
||||
seq = generate(iAry, terms) ' Obtain next expression.
|
||||
sVal = eval(seq) ' Obtain next evaluation.
|
||||
If sVal >= 0 Then ' Don't bother saving the negative results.
|
||||
If res.Contains(sVal) Then tally(res.IndexOf(sVal)) += 1 _
|
||||
Else res.Add(sVal) : tally.Add(1)
|
||||
If sVal = targSum Then _
|
||||
Console.WriteLine(" {0,2} {1}", sCnt, seq) : sCnt += 1
|
||||
End If
|
||||
Loop Until plusOne(iAry, lastDig) < 0
|
||||
reSort(tally, res) ' Sort by tally to find result with the most solutions.
|
||||
Console.WriteLine("The sum that has the the most solutions is {0}, (at {1}).",
|
||||
res.Last, tally.Last)
|
||||
reSort(res, tally) ' Sort by result to find first missing result and top results.
|
||||
Console.WriteLine("The lowest positive sum that can't be expressed is {0}.",
|
||||
firstMiss(res))
|
||||
Console.WriteLine("The ten highest numbers that can be expressed are:")
|
||||
res.Reverse() ' To let us take the last items for output.
|
||||
sCnt = 0 ' Keep track of items displayed (for formatting).
|
||||
For Each item As Integer In res.Take(highNums)
|
||||
Console.Write("{0, -11}", item)
|
||||
sCnt = (sCnt + 1) Mod 5 : If sCnt = 0 Then Console.WriteLine()
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Sub Main()
|
||||
Solve100() ' if interested, try this: Solve100("987654321")
|
||||
End Sub
|
||||
106
Task/Sum-to-100/Wren/sum-to-100.wren
Normal file
106
Task/Sum-to-100/Wren/sum-to-100.wren
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import "/dynamic" for Enum
|
||||
import "/fmt" for Fmt
|
||||
import "/set" for Set
|
||||
import "/math" for Nums
|
||||
import "/sort" for Sort
|
||||
|
||||
var Op = Enum.create("Op", ["ADD", "SUB", "JOIN"])
|
||||
|
||||
var NUMBER_OF_DIGITS = 9
|
||||
var THREE_POW_4 = 3 * 3 * 3 * 3
|
||||
var NUMBER_OF_EXPRESSIONS = 2 * THREE_POW_4 * THREE_POW_4
|
||||
|
||||
class Expression {
|
||||
static print(givenSum) {
|
||||
var expr = Expression.new()
|
||||
for (i in 0...NUMBER_OF_EXPRESSIONS) {
|
||||
if (expr.toInt == givenSum) Fmt.print("$9d = $s", givenSum, expr)
|
||||
expr.inc
|
||||
}
|
||||
}
|
||||
|
||||
construct new() {
|
||||
_code = List.filled(NUMBER_OF_DIGITS, Op.ADD)
|
||||
}
|
||||
|
||||
inc {
|
||||
for (i in 0..._code.count) {
|
||||
_code[i] = (_code[i] == Op.ADD) ? Op.SUB : (_code[i] == Op.SUB) ? Op.JOIN : Op.ADD
|
||||
if (_code[i] != Op.ADD) break
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
toInt {
|
||||
var value = 0
|
||||
var number = 0
|
||||
var sign = 1
|
||||
for (digit in 1..9) {
|
||||
var c = _code[NUMBER_OF_DIGITS - digit]
|
||||
if (c == Op.ADD) {
|
||||
value = value + sign * number
|
||||
number = digit
|
||||
sign = 1
|
||||
} else if (c == Op.SUB) {
|
||||
value = value + sign * number
|
||||
number = digit
|
||||
sign = -1
|
||||
} else {
|
||||
number = 10 * number + digit
|
||||
}
|
||||
}
|
||||
return value + sign * number
|
||||
}
|
||||
|
||||
toString {
|
||||
var sb = ""
|
||||
for (digit in 1..NUMBER_OF_DIGITS) {
|
||||
var c = _code[NUMBER_OF_DIGITS - digit]
|
||||
if (c == Op.ADD) {
|
||||
if (digit > 1) sb = sb + " + "
|
||||
} else if (c == Op.SUB) {
|
||||
sb = sb + " - "
|
||||
}
|
||||
sb = sb + digit.toString
|
||||
}
|
||||
return sb.trimStart()
|
||||
}
|
||||
}
|
||||
|
||||
class Stat {
|
||||
construct new() {
|
||||
_countSum = {}
|
||||
_sumCount = {}
|
||||
var expr = Expression.new()
|
||||
for (i in 0...NUMBER_OF_EXPRESSIONS) {
|
||||
var sum = expr.toInt
|
||||
_countSum[sum] = _countSum[sum] ? 1 + _countSum[sum] : 1
|
||||
expr.inc
|
||||
}
|
||||
for (me in _countSum) {
|
||||
var set = _sumCount.containsKey(me.value) ? _sumCount[me.value] : Set.new()
|
||||
set.add(me.key)
|
||||
_sumCount[me.value] = set
|
||||
}
|
||||
}
|
||||
|
||||
countSum { _countSum }
|
||||
sumCount { _sumCount }
|
||||
}
|
||||
|
||||
System.print("100 has the following solutions:\n")
|
||||
Expression.print(100)
|
||||
|
||||
var stat = Stat.new()
|
||||
var maxCount = Nums.max(stat.sumCount.keys)
|
||||
var maxSum = Nums.max(stat.sumCount[maxCount])
|
||||
System.print("\n%(maxSum) has the maximum number of solutions, namely %(maxCount)")
|
||||
|
||||
var value = 0
|
||||
while (stat.countSum.containsKey(value)) value = value + 1
|
||||
System.print("\n%(value) is the lowest positive number with no solutions")
|
||||
|
||||
System.print("\nThe ten highest numbers that do have solutions are:\n")
|
||||
var res = stat.countSum.keys.toList
|
||||
Sort.quick(res)
|
||||
res[-1..0].take(10).each { |e| Expression.print(e) }
|
||||
15
Task/Sum-to-100/Zkl/sum-to-100-1.zkl
Normal file
15
Task/Sum-to-100/Zkl/sum-to-100-1.zkl
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
var all = // ( (1,12,123...-1,-12,...), (2,23,...) ...)
|
||||
(9).pump(List,fcn(n){ split("123456789"[n,*]) }) // 45
|
||||
.apply(fcn(ns){ ns.extend(ns.copy().apply('*(-1))) }); // 90
|
||||
fcn calcAllSums{ // calculate all 6572 sums (1715 unique)
|
||||
fcn(n,sum,soFar,r){
|
||||
if(n==9) return();
|
||||
foreach b in (all[n]){
|
||||
if(sum+b>=0 and b.abs()%10==9) r.appendV(sum+b,"%s%+d".fmt(soFar,b));
|
||||
self.fcn(b.abs()%10,sum + b,"%s%+d".fmt(soFar,b),r);
|
||||
}
|
||||
}(0,0,"",r:=Dictionary());
|
||||
r
|
||||
}
|
||||
// "123" --> (1,12,123)
|
||||
fcn split(nstr){ (1).pump(nstr.len(),List,nstr.get.fp(0),"toInt") }
|
||||
20
Task/Sum-to-100/Zkl/sum-to-100-2.zkl
Normal file
20
Task/Sum-to-100/Zkl/sum-to-100-2.zkl
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
fcn showSums(allSums,N=100,printSolutions=2){
|
||||
slns:=allSums.find(N,T);
|
||||
if(printSolutions) println("%d solutions for N=%d".fmt(slns.len(),N));
|
||||
if(printSolutions==2) println(slns.concat("\n"));
|
||||
println();
|
||||
}
|
||||
|
||||
allSums:=calcAllSums();
|
||||
showSums(allSums);
|
||||
showSums(allSums,0,1);
|
||||
|
||||
println("Smallest postive integer with no solution: ",
|
||||
[1..].filter1('wrap(n){ Void==allSums.find(n) }));
|
||||
|
||||
println("5 commonest sums (sum, number of ways to calculate to it):");
|
||||
ms:=allSums.values.apply("len").sort()[-5,*]; // 5 mostest sums
|
||||
allSums.pump(List, // get those pairs
|
||||
'wrap([(k,v)]){ v=v.len(); ms.holds(v) and T(k.toInt(),v) or Void.Skip })
|
||||
.sort(fcn(kv1,kv2){ kv1[1]>kv2[1] }) // and sort
|
||||
.println();
|
||||
Loading…
Add table
Add a link
Reference in a new issue