Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
4
Task/Nonoblock/00-META.yaml
Normal file
4
Task/Nonoblock/00-META.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category:
|
||||
- Puzzles
|
||||
from: http://rosettacode.org/wiki/Nonoblock
|
||||
63
Task/Nonoblock/00-TASK.txt
Normal file
63
Task/Nonoblock/00-TASK.txt
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
Nonoblock is a chip off the old [[Nonogram solver|Nonogram]] puzzle.
|
||||
|
||||
|
||||
;Given:
|
||||
* The number of cells in a row.
|
||||
* The size of each, (space separated), connected block of cells to fit in the row, in left-to right order.
|
||||
|
||||
|
||||
;Task:
|
||||
* show all possible positions.
|
||||
* show the number of positions of the blocks for the following cases within the row.
|
||||
* show all output on this page.
|
||||
* use a "neat" diagram of the block positions.
|
||||
|
||||
|
||||
;Enumerate the following configurations:
|
||||
# '''5''' cells and '''[2, 1]''' blocks
|
||||
# '''5''' cells and '''[]''' blocks (no blocks)
|
||||
# '''10''' cells and '''[8]''' blocks
|
||||
# '''15''' cells and '''[2, 3, 2, 3]''' blocks
|
||||
# '''5''' cells and '''[2, 3]''' blocks (should give some indication of this not being possible)
|
||||
|
||||
|
||||
;Example:
|
||||
Given a row of five cells and a block of two cells followed by a block of one cell - in that order, the example could be shown as:
|
||||
|
||||
|_|_|_|_|_| # 5 cells and [2, 1] blocks
|
||||
|
||||
And would expand to the following 3 possible rows of block positions:
|
||||
|
||||
|A|A|_|B|_|
|
||||
|A|A|_|_|B|
|
||||
|_|A|A|_|B|
|
||||
|
||||
|
||||
Note how the sets of blocks are always separated by a space.
|
||||
|
||||
Note also that it is not necessary for each block to have a separate letter.
|
||||
Output approximating
|
||||
|
||||
This:
|
||||
|#|#|_|#|_|
|
||||
|#|#|_|_|#|
|
||||
|_|#|#|_|#|
|
||||
|
||||
This would also work:
|
||||
##.#.
|
||||
##..#
|
||||
.##.#
|
||||
|
||||
|
||||
;An algorithm:
|
||||
* Find the minimum space to the right that is needed to legally hold all but the leftmost block of cells (with a space between blocks remember).
|
||||
* The leftmost cell can legitimately be placed in all positions from the LHS up to a RH position that allows enough room for the rest of the blocks.
|
||||
* for each position of the LH block recursively compute the position of the rest of the blocks in the ''remaining'' space to the right of the current placement of the LH block.
|
||||
|
||||
(This is the algorithm used in the [[Nonoblock#Python]] solution).
|
||||
|
||||
|
||||
;Reference:
|
||||
* The blog post [http://paddy3118.blogspot.co.uk/2014/03/nonogram-puzzle-solver-part-1.html Nonogram puzzle solver (part 1)] Inspired this task and donated its [[Nonoblock#Python]] solution.
|
||||
<br><br>
|
||||
|
||||
42
Task/Nonoblock/11l/nonoblock.11l
Normal file
42
Task/Nonoblock/11l/nonoblock.11l
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
F nonoblocks([Int] &blocks, Int cells) -> [[(Int, Int)]]
|
||||
[[(Int, Int)]] r
|
||||
I blocks.empty | blocks[0] == 0
|
||||
r [+]= [(0, 0)]
|
||||
E
|
||||
assert(sum(blocks) + blocks.len - 1 <= cells, ‘Those blocks will not fit in those cells’)
|
||||
V (blength, brest) = (blocks[0], blocks[1..])
|
||||
V minspace4rest = sum(brest.map(b -> 1 + b))
|
||||
|
||||
L(bpos) 0 .. cells - minspace4rest - blength
|
||||
I brest.empty
|
||||
r [+]= [(bpos, blength)]
|
||||
E
|
||||
V offset = bpos + blength + 1
|
||||
L(subpos) nonoblocks(&brest, cells - offset)
|
||||
V rest = subpos.map((bp, bl) -> (@offset + bp, bl))
|
||||
V vec = [(bpos, blength)] [+] rest
|
||||
r [+]= vec
|
||||
R r
|
||||
|
||||
F pblock(vec, cells)
|
||||
‘Prettyprints each run of blocks with a different letter A.. for each block of filled cells’
|
||||
V vector = [‘_’] * cells
|
||||
L(bp_bl) vec
|
||||
V ch = L.index + ‘A’.code
|
||||
V (bp, bl) = bp_bl
|
||||
L(i) bp .< bp + bl
|
||||
vector[i] = I vector[i] == ‘_’ {Char(code' ch)} E Char(‘?’)
|
||||
R ‘|’vector.join(‘|’)‘|’
|
||||
|
||||
L(blocks, cells) [
|
||||
([2, 1], 5),
|
||||
([Int](), 5),
|
||||
([8], 10),
|
||||
([2, 3, 2, 3], 15)
|
||||
]
|
||||
print("\nConfiguration:\n #. ## #. cells and #. blocks".format(pblock([(Int, Int)](), cells), cells, blocks))
|
||||
print(‘ Possibilities:’)
|
||||
V nb = nonoblocks(&blocks, cells)
|
||||
L(vector) nb
|
||||
print(‘ ’pblock(vector, cells))
|
||||
print(‘ A total of #. Possible configurations.’.format(nb.len))
|
||||
115
Task/Nonoblock/Action-/nonoblock.action
Normal file
115
Task/Nonoblock/Action-/nonoblock.action
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
DEFINE MAX_BLOCKS="10"
|
||||
DEFINE NOT_FOUND="255"
|
||||
|
||||
BYTE FUNC GetBlockAtPos(BYTE p BYTE ARRAY blocks,pos INT count)
|
||||
INT i
|
||||
FOR i=0 TO count-1
|
||||
DO
|
||||
IF p>=pos(i) AND p<pos(i)+blocks(i) THEN
|
||||
RETURN (i)
|
||||
FI
|
||||
OD
|
||||
RETURN (NOT_FOUND)
|
||||
|
||||
PROC PrintResult(BYTE cells BYTE ARRAY blocks,pos INT count)
|
||||
BYTE i,b
|
||||
|
||||
Print("[")
|
||||
FOR i=0 TO cells-1
|
||||
DO
|
||||
b=GetBlockAtPos(i,blocks,pos,count)
|
||||
IF b=NOT_FOUND THEN
|
||||
Put('.)
|
||||
ELSE
|
||||
Put(b+'A)
|
||||
FI
|
||||
OD
|
||||
PrintE("]")
|
||||
RETURN
|
||||
|
||||
BYTE FUNC LeftMostPos(BYTE cells BYTE ARRAY blocks,pos INT count,startFrom)
|
||||
INT i
|
||||
|
||||
FOR i=startFrom TO count-1
|
||||
DO
|
||||
pos(i)=pos(i-1)+blocks(i-1)+1
|
||||
IF pos(i)+blocks(i)>cells THEN
|
||||
RETURN (0)
|
||||
FI
|
||||
OD
|
||||
RETURN (1)
|
||||
|
||||
BYTE FUNC MoveToRight(BYTE cells BYTE ARRAY blocks,pos INT count,startFrom)
|
||||
pos(startFrom)==+1
|
||||
IF pos(startFrom)+blocks(startFrom)>cells THEN
|
||||
RETURN (0)
|
||||
FI
|
||||
RETURN (LeftMostPos(cells,blocks,pos,count,startFrom+1))
|
||||
|
||||
PROC Process(BYTE cells BYTE ARRAY blocks INT count)
|
||||
BYTE ARRAY pos(MAX_BLOCKS)
|
||||
BYTE success
|
||||
INT current
|
||||
|
||||
IF count=0 THEN
|
||||
PrintResult(cells,blocks,pos,count)
|
||||
RETURN
|
||||
FI
|
||||
|
||||
pos(0)=0
|
||||
success=LeftMostPos(cells,blocks,pos,count,1)
|
||||
IF success=0 THEN
|
||||
PrintE("No solutions")
|
||||
RETURN
|
||||
FI
|
||||
current=count-1
|
||||
WHILE success
|
||||
DO
|
||||
PrintResult(cells,blocks,pos,count)
|
||||
DO
|
||||
success=MoveToRight(cells,blocks,pos,count,current)
|
||||
IF success THEN
|
||||
current=count-1
|
||||
ELSE
|
||||
current==-1
|
||||
IF current<0 THEN
|
||||
EXIT
|
||||
FI
|
||||
FI
|
||||
UNTIL success
|
||||
OD
|
||||
OD
|
||||
RETURN
|
||||
|
||||
PROC Test(BYTE cells BYTE ARRAY blocks INT count)
|
||||
BYTE CH=$02FC ;Internal hardware value for last key pressed
|
||||
INT i
|
||||
|
||||
PrintB(cells) Print(" cells [")
|
||||
FOR i=0 TO count-1
|
||||
DO
|
||||
PrintB(blocks(i))
|
||||
IF i<count-1 THEN
|
||||
Put(32)
|
||||
FI
|
||||
OD
|
||||
PrintE("]")
|
||||
|
||||
Process(cells,blocks,count)
|
||||
|
||||
PutE()
|
||||
PrintE("Press any key to continue...")
|
||||
DO UNTIL CH#$FF OD
|
||||
CH=$FF
|
||||
PutE()
|
||||
RETURN
|
||||
|
||||
PROC Main()
|
||||
BYTE ARRAY t1=[2 1],t2=[],t3=[8],t4=[2 3 2 3],t5=[2 3]
|
||||
|
||||
Test(5,t1,2)
|
||||
Test(5,t2,0)
|
||||
Test(10,t3,1)
|
||||
Test(15,t4,4)
|
||||
Test(5,t5,2)
|
||||
RETURN
|
||||
75
Task/Nonoblock/AutoHotkey/nonoblock-1.ahk
Normal file
75
Task/Nonoblock/AutoHotkey/nonoblock-1.ahk
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
;-------------------------------------------
|
||||
NonoBlock(cells, blocks){
|
||||
result := [], line := ""
|
||||
for i, v in blocks
|
||||
B .= v ", "
|
||||
output := cells " cells and [" Trim(B, ", ") "] blocks`n"
|
||||
|
||||
if ((Arr := NonoBlockCreate(cells, blocks)) = "Error")
|
||||
return output "No Solution`n"
|
||||
for i, v in arr
|
||||
line.= v ";"
|
||||
result[line] := true
|
||||
result := NonoBlockRecurse(Arr, result)
|
||||
output .= NonoBlockShow(result)
|
||||
return output
|
||||
}
|
||||
;-------------------------------------------
|
||||
; create cells+1 size array, stack blocks to left with one gap in between
|
||||
; gaps are represented by negative number
|
||||
; stack extra gaps to far left
|
||||
; for example : 6 cells and [2, 1] blocks
|
||||
; returns [-2, 2, -1, 1, 0, 0, 0]
|
||||
NonoBlockCreate(cells, blocks){
|
||||
Arr := [], B := blocks.Count()
|
||||
if !B ; no blocks
|
||||
return [0-cells, 0]
|
||||
for i, v in blocks{
|
||||
total += v
|
||||
Arr.InsertAt(1, blocks[B-A_Index+1])
|
||||
Arr.InsertAt(1, -1)
|
||||
}
|
||||
if (cells < total + B-1) ; not possible
|
||||
return "Error"
|
||||
Arr[1] := total + B-1 - cells
|
||||
loop % cells - Arr.Count() + 1
|
||||
Arr.Push(0)
|
||||
return Arr
|
||||
}
|
||||
;-------------------------------------------
|
||||
; shift negative numbers from left to right recursively.
|
||||
; preserve at least one gap between blocks.
|
||||
; [-2, 2, -1, 1, 0, 0, 0]
|
||||
; [-1, 2, -2, 1, 0, 0, 0]
|
||||
NonoBlockRecurse(Arr, result, pos:= 1){
|
||||
i := pos-1
|
||||
while (i < Arr.count())
|
||||
{
|
||||
if ((B:=Arr[++i])>=0) || (B=-1 && i>1)
|
||||
continue
|
||||
if (i=Arr.count()-1)
|
||||
return result
|
||||
Arr[i] := ++B, Arr[i+2] := Arr[i+2] -1
|
||||
result := NonoBlockRecurse(Arr.Clone(), result, i)
|
||||
line := []
|
||||
for k, v in Arr
|
||||
line.=v ";"
|
||||
result[line] := true
|
||||
}
|
||||
return result
|
||||
}
|
||||
;-------------------------------------------
|
||||
; represent positve numbers by a block of "#", negative nubmers by a block of "."
|
||||
NonoBlockShow(result){
|
||||
for line in result{
|
||||
i := A_Index
|
||||
nLine := ""
|
||||
for j, val in StrSplit(line, ";")
|
||||
loop % Abs(val)
|
||||
nLine .= val > 0 ? "#" : "."
|
||||
output .= nLine "`n"
|
||||
}
|
||||
Sort, output, U
|
||||
return output
|
||||
}
|
||||
;-------------------------------------------
|
||||
7
Task/Nonoblock/AutoHotkey/nonoblock-2.ahk
Normal file
7
Task/Nonoblock/AutoHotkey/nonoblock-2.ahk
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Results .= NonoBlock(5, [2, 1]) "------------`n"
|
||||
Results .= NonoBlock(5, []) "------------`n"
|
||||
Results .= NonoBlock(10, [8]) "------------`n"
|
||||
Results .= NonoBlock(15, [2, 3, 2, 3]) "------------`n"
|
||||
Results .= NonoBlock(5, [2, 3]) "------------`n"
|
||||
MsgBox, 262144, , % Results
|
||||
return
|
||||
99
Task/Nonoblock/C++/nonoblock.cpp
Normal file
99
Task/Nonoblock/C++/nonoblock.cpp
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
typedef std::pair<int, std::vector<int> > puzzle;
|
||||
|
||||
class nonoblock {
|
||||
public:
|
||||
void solve( std::vector<puzzle>& p ) {
|
||||
for( std::vector<puzzle>::iterator i = p.begin(); i != p.end(); i++ ) {
|
||||
counter = 0;
|
||||
std::cout << " Puzzle: " << ( *i ).first << " cells and blocks [ ";
|
||||
for( std::vector<int>::iterator it = ( *i ).second.begin(); it != ( *i ).second.end(); it++ )
|
||||
std::cout << *it << " ";
|
||||
std::cout << "] ";
|
||||
int s = std::accumulate( ( *i ).second.begin(), ( *i ).second.end(), 0 ) + ( ( *i ).second.size() > 0 ? ( *i ).second.size() - 1 : 0 );
|
||||
if( ( *i ).first - s < 0 ) {
|
||||
std::cout << "has no solution!\n\n\n";
|
||||
continue;
|
||||
}
|
||||
std::cout << "\n Possible configurations:\n\n";
|
||||
std::string b( ( *i ).first, '-' );
|
||||
solve( *i, b, 0 );
|
||||
std::cout << "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void solve( puzzle p, std::string n, int start ) {
|
||||
if( p.second.size() < 1 ) {
|
||||
output( n );
|
||||
return;
|
||||
}
|
||||
std::string temp_string;
|
||||
int offset,
|
||||
this_block_size = p.second[0];
|
||||
|
||||
int space_need_for_others = std::accumulate( p.second.begin() + 1, p.second.end(), 0 );
|
||||
space_need_for_others += p.second.size() - 1;
|
||||
|
||||
int space_for_curr_block = p.first - space_need_for_others - std::accumulate( p.second.begin(), p.second.begin(), 0 );
|
||||
|
||||
std::vector<int> v1( p.second.size() - 1 );
|
||||
std::copy( p.second.begin() + 1, p.second.end(), v1.begin() );
|
||||
puzzle p1 = std::make_pair( space_need_for_others, v1 );
|
||||
|
||||
for( int a = 0; a < space_for_curr_block; a++ ) {
|
||||
temp_string = n;
|
||||
|
||||
if( start + this_block_size > n.length() ) return;
|
||||
|
||||
for( offset = start; offset < start + this_block_size; offset++ )
|
||||
temp_string.at( offset ) = 'o';
|
||||
|
||||
if( p1.first ) solve( p1, temp_string, offset + 1 );
|
||||
else output( temp_string );
|
||||
|
||||
start++;
|
||||
}
|
||||
}
|
||||
void output( std::string s ) {
|
||||
char b = 65 - ( s.at( 0 ) == '-' ? 1 : 0 );
|
||||
bool f = false;
|
||||
std::cout << std::setw( 3 ) << ++counter << "\t|";
|
||||
for( std::string::iterator i = s.begin(); i != s.end(); i++ ) {
|
||||
b += ( *i ) == 'o' && f ? 1 : 0;
|
||||
std::cout << ( ( *i ) == 'o' ? b : '_' ) << "|";
|
||||
f = ( *i ) == '-' ? true : false;
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
unsigned counter;
|
||||
};
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
std::vector<puzzle> problems;
|
||||
std::vector<int> blocks;
|
||||
blocks.push_back( 2 ); blocks.push_back( 1 );
|
||||
problems.push_back( std::make_pair( 5, blocks ) );
|
||||
blocks.clear();
|
||||
problems.push_back( std::make_pair( 5, blocks ) );
|
||||
blocks.push_back( 8 );
|
||||
problems.push_back( std::make_pair( 10, blocks ) );
|
||||
blocks.clear();
|
||||
blocks.push_back( 2 ); blocks.push_back( 3 );
|
||||
problems.push_back( std::make_pair( 5, blocks ) );
|
||||
blocks.push_back( 2 ); blocks.push_back( 3 );
|
||||
problems.push_back( std::make_pair( 15, blocks ) );
|
||||
|
||||
nonoblock nn;
|
||||
nn.solve( problems );
|
||||
|
||||
return 0;
|
||||
}
|
||||
51
Task/Nonoblock/C-sharp/nonoblock.cs
Normal file
51
Task/Nonoblock/C-sharp/nonoblock.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
public static class Nonoblock
|
||||
{
|
||||
public static void Main() {
|
||||
Positions(5, 2,1);
|
||||
Positions(5);
|
||||
Positions(10, 8);
|
||||
Positions(15, 2,3,2,3);
|
||||
Positions(5, 2,3);
|
||||
}
|
||||
|
||||
public static void Positions(int cells, params int[] blocks) {
|
||||
if (cells < 0 || blocks == null || blocks.Any(b => b < 1)) throw new ArgumentOutOfRangeException();
|
||||
Console.WriteLine($"{cells} cells with [{string.Join(", ", blocks)}]");
|
||||
if (blocks.Sum() + blocks.Length - 1 > cells) {
|
||||
Console.WriteLine("No solution");
|
||||
return;
|
||||
}
|
||||
var spaces = new int[blocks.Length + 1];
|
||||
int total = -1;
|
||||
for (int i = 0; i < blocks.Length; i++) {
|
||||
total += blocks[i] + 1;
|
||||
spaces[i+1] = total;
|
||||
}
|
||||
spaces[spaces.Length - 1] = cells - 1;
|
||||
var sb = new StringBuilder(string.Join(".", blocks.Select(b => new string('#', b))).PadRight(cells, '.'));
|
||||
Iterate(sb, spaces, spaces.Length - 1, 0);
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
private static void Iterate(StringBuilder output, int[] spaces, int index, int offset) {
|
||||
Console.WriteLine(output.ToString());
|
||||
if (index <= 0) return;
|
||||
int count = 0;
|
||||
while (output[spaces[index] - offset] != '#') {
|
||||
count++;
|
||||
output.Remove(spaces[index], 1);
|
||||
output.Insert(spaces[index-1], '.');
|
||||
spaces[index-1]++;
|
||||
Iterate(output, spaces, index - 1, 1);
|
||||
}
|
||||
if (offset == 0) return;
|
||||
spaces[index-1] -= count;
|
||||
output.Remove(spaces[index-1], count);
|
||||
output.Insert(spaces[index] - count, ".", count);
|
||||
}
|
||||
|
||||
}
|
||||
63
Task/Nonoblock/C/nonoblock.c
Normal file
63
Task/Nonoblock/C/nonoblock.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void nb(int cells, int total_block_size, int* blocks, int block_count,
|
||||
char* output, int offset, int* count) {
|
||||
if (block_count == 0) {
|
||||
printf("%2d %s\n", ++*count, output);
|
||||
return;
|
||||
}
|
||||
int block_size = blocks[0];
|
||||
int max_pos = cells - (total_block_size + block_count - 1);
|
||||
total_block_size -= block_size;
|
||||
cells -= block_size + 1;
|
||||
++blocks;
|
||||
--block_count;
|
||||
for (int i = 0; i <= max_pos; ++i, --cells) {
|
||||
memset(output + offset, '.', max_pos + block_size);
|
||||
memset(output + offset + i, '#', block_size);
|
||||
nb(cells, total_block_size, blocks, block_count, output,
|
||||
offset + block_size + i + 1, count);
|
||||
}
|
||||
}
|
||||
|
||||
void nonoblock(int cells, int* blocks, int block_count) {
|
||||
printf("%d cells and blocks [", cells);
|
||||
for (int i = 0; i < block_count; ++i)
|
||||
printf(i == 0 ? "%d" : ", %d", blocks[i]);
|
||||
printf("]:\n");
|
||||
int total_block_size = 0;
|
||||
for (int i = 0; i < block_count; ++i)
|
||||
total_block_size += blocks[i];
|
||||
if (cells < total_block_size + block_count - 1) {
|
||||
printf("no solution\n");
|
||||
return;
|
||||
}
|
||||
char output[cells + 1];
|
||||
memset(output, '.', cells);
|
||||
output[cells] = '\0';
|
||||
int count = 0;
|
||||
nb(cells, total_block_size, blocks, block_count, output, 0, &count);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int blocks1[] = {2, 1};
|
||||
nonoblock(5, blocks1, 2);
|
||||
printf("\n");
|
||||
|
||||
nonoblock(5, NULL, 0);
|
||||
printf("\n");
|
||||
|
||||
int blocks2[] = {8};
|
||||
nonoblock(10, blocks2, 1);
|
||||
printf("\n");
|
||||
|
||||
int blocks3[] = {2, 3, 2, 3};
|
||||
nonoblock(15, blocks3, 4);
|
||||
printf("\n");
|
||||
|
||||
int blocks4[] = {2, 3};
|
||||
nonoblock(5, blocks4, 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
84
Task/Nonoblock/D/nonoblock.d
Normal file
84
Task/Nonoblock/D/nonoblock.d
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import std.stdio, std.array, std.algorithm, std.exception, std.conv,
|
||||
std.concurrency, std.range;
|
||||
|
||||
struct Solution { uint pos, len; }
|
||||
|
||||
Generator!(Solution[]) nonoBlocks(in uint[] blocks, in uint cells) {
|
||||
return new typeof(return)({
|
||||
if (blocks.empty || blocks[0] == 0) {
|
||||
yield([Solution(0, 0)]);
|
||||
} else {
|
||||
enforce(blocks.sum + blocks.length - 1 <= cells,
|
||||
"Those blocks cannot fit in those cells.");
|
||||
immutable firstBl = blocks[0];
|
||||
const restBl = blocks.dropOne;
|
||||
|
||||
// The other blocks need space.
|
||||
immutable minS = restBl.map!(b => b + 1).sum;
|
||||
|
||||
// Slide the start position from left to max RH
|
||||
// index allowing for other blocks.
|
||||
foreach (immutable bPos; 0 .. cells - minS - firstBl + 1) {
|
||||
if (restBl.empty) {
|
||||
// No other blocks to the right so just yield
|
||||
// this one.
|
||||
yield([Solution(bPos, firstBl)]);
|
||||
} else {
|
||||
// More blocks to the right so create a sub-problem
|
||||
// of placing the restBl blocks in the cells one
|
||||
// space to the right of the RHS of this block.
|
||||
immutable offset = bPos + firstBl + 1;
|
||||
immutable newCells = cells - offset;
|
||||
|
||||
// Recursive call to nonoBlocks yields multiple
|
||||
// sub-positions.
|
||||
foreach (const subPos; nonoBlocks(restBl, newCells)) {
|
||||
// Remove the offset from sub block positions.
|
||||
auto rest = subPos.map!(sol => Solution(offset + sol.pos, sol.len));
|
||||
|
||||
// Yield this block plus sub blocks positions.
|
||||
yield(Solution(bPos, firstBl) ~ rest.array);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/// Pretty prints each run of blocks with a
|
||||
/// different letter for each block of filled cells.
|
||||
string show(in Solution[] vec, in uint nCells) pure {
|
||||
auto result = ['_'].replicate(nCells);
|
||||
foreach (immutable i, immutable sol; vec)
|
||||
foreach (immutable j; sol.pos .. sol.pos + sol.len)
|
||||
result[j] = (result[j] == '_') ? to!char('A' + i) : '?';
|
||||
return '[' ~ result ~ ']';
|
||||
}
|
||||
|
||||
void main() {
|
||||
static struct Problem { uint[] blocks; uint nCells; }
|
||||
|
||||
immutable Problem[] problems = [{[2, 1], 5},
|
||||
{[], 5},
|
||||
{[8], 10},
|
||||
{[2, 3, 2, 3], 15},
|
||||
{[4, 3], 10},
|
||||
{[2, 1], 5},
|
||||
{[3, 1], 10},
|
||||
{[2, 3], 5}];
|
||||
|
||||
foreach (immutable prob; problems) {
|
||||
writefln("Configuration (%d cells and %s blocks):",
|
||||
prob.nCells, prob.blocks);
|
||||
show([], prob.nCells).writeln;
|
||||
"Possibilities:".writeln;
|
||||
auto nConfigs = 0;
|
||||
foreach (const sol; nonoBlocks(prob.tupleof)) {
|
||||
show(sol, prob.nCells).writeln;
|
||||
nConfigs++;
|
||||
}
|
||||
writefln("A total of %d possible configurations.", nConfigs);
|
||||
writeln;
|
||||
}
|
||||
}
|
||||
45
Task/Nonoblock/EchoLisp/nonoblock.l
Normal file
45
Task/Nonoblock/EchoLisp/nonoblock.l
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
;; size is the remaining # of cells
|
||||
;; blocks is the list of remaining blocks size
|
||||
;; cells is a stack where we push 0 = space or block size.
|
||||
(define (nonoblock size blocks into: cells)
|
||||
(cond
|
||||
((and (empty? blocks) (= 0 size)) (print-cells (stack->list cells)))
|
||||
|
||||
((<= size 0) #f) ;; no hope - cut search
|
||||
((> (apply + blocks) size) #f) ;; no hope - cut search
|
||||
|
||||
(else
|
||||
(push cells 0) ;; space
|
||||
(nonoblock (1- size) blocks cells)
|
||||
(pop cells)
|
||||
|
||||
(when (!empty? blocks)
|
||||
(when (stack-empty? cells) ;; first one (no space is allowed)
|
||||
(push cells (first blocks))
|
||||
(nonoblock (- size (first blocks)) (rest blocks) cells)
|
||||
(pop cells))
|
||||
|
||||
(push cells 0) ;; add space before
|
||||
(push cells (first blocks))
|
||||
(nonoblock (- size (first blocks) 1) (rest blocks) cells)
|
||||
(pop cells)
|
||||
(pop cells)))))
|
||||
|
||||
(string-delimiter "")
|
||||
(define block-symbs #( ? 📦 💣 💊 🍒 🌽 📘 📙 💰 🍯 ))
|
||||
|
||||
(define (print-cells cells)
|
||||
(writeln (string-append "|"
|
||||
(for/string ((cell cells))
|
||||
(if (zero? cell) "_"
|
||||
(for/string ((i cell)) [block-symbs cell]))) "|")))
|
||||
|
||||
(define (task nonotest)
|
||||
(for ((test nonotest))
|
||||
(define size (first test))
|
||||
(define blocks (second test))
|
||||
(printf "\n size:%d blocks:%d" size blocks)
|
||||
(if
|
||||
(> (+ (apply + blocks)(1- (length blocks))) size)
|
||||
(writeln "❌ no solution for" size blocks)
|
||||
(nonoblock size blocks (stack 'cells)))))
|
||||
63
Task/Nonoblock/Elixir/nonoblock.elixir
Normal file
63
Task/Nonoblock/Elixir/nonoblock.elixir
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
defmodule Nonoblock do
|
||||
def solve(cell, blocks) do
|
||||
width = Enum.sum(blocks) + length(blocks) - 1
|
||||
if cell < width do
|
||||
raise "Those blocks will not fit in those cells"
|
||||
else
|
||||
nblocks(cell, blocks, "")
|
||||
end
|
||||
end
|
||||
|
||||
defp nblocks(cell, _, position) when cell<=0, do:
|
||||
display(String.slice(position, 0..cell-1))
|
||||
defp nblocks(cell, blocks, position) when length(blocks)==0 or hd(blocks)==0, do:
|
||||
display(position <> String.duplicate(".", cell))
|
||||
defp nblocks(cell, blocks, position) do
|
||||
rest = cell - Enum.sum(blocks) - length(blocks) + 2
|
||||
[bl | brest] = blocks
|
||||
Enum.reduce(0..rest-1, 0, fn i,acc ->
|
||||
acc + nblocks(cell-i-bl-1, brest, position <> String.duplicate(".", i) <> String.duplicate("#",bl) <> ".")
|
||||
end)
|
||||
end
|
||||
|
||||
defp display(str) do
|
||||
IO.puts nonocell(str)
|
||||
1 # number of positions
|
||||
end
|
||||
|
||||
def nonocell(str) do # "##.###..##" -> "|A|A|_|B|B|B|_|_|C|C|"
|
||||
slist = String.to_char_list(str) |> Enum.chunk_by(&(&1==?.)) |> Enum.map(&List.to_string(&1))
|
||||
chrs = Enum.map(?A..?Z, &List.to_string([&1]))
|
||||
result = nonocell_replace(slist, chrs, "")
|
||||
|> String.replace(".", "_")
|
||||
|> String.split("") |> Enum.join("|")
|
||||
"|" <> result
|
||||
end
|
||||
|
||||
defp nonocell_replace([], _, result), do: result
|
||||
defp nonocell_replace([h|t], chrs, result) do
|
||||
if String.first(h) == "#" do
|
||||
[c | rest] = chrs
|
||||
nonocell_replace(t, rest, result <> String.replace(h, "#", c))
|
||||
else
|
||||
nonocell_replace(t, chrs, result <> h)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
conf = [{ 5, [2, 1]},
|
||||
{ 5, []},
|
||||
{10, [8]},
|
||||
{15, [2, 3, 2, 3]},
|
||||
{ 5, [2, 3]} ]
|
||||
Enum.each(conf, fn {cell, blocks} ->
|
||||
try do
|
||||
IO.puts "Configuration:"
|
||||
IO.puts "#{Nonoblock.nonocell(String.duplicate(".",cell))} # #{cell} cells and #{inspect blocks} blocks"
|
||||
IO.puts "Possibilities:"
|
||||
count = Nonoblock.solve(cell, blocks)
|
||||
IO.puts "A total of #{count} Possible configurations.\n"
|
||||
rescue
|
||||
e in RuntimeError -> IO.inspect e
|
||||
end
|
||||
end)
|
||||
48
Task/Nonoblock/Go/nonoblock.go
Normal file
48
Task/Nonoblock/Go/nonoblock.go
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func printBlock(data string, le int) {
|
||||
a := []byte(data)
|
||||
sumBytes := 0
|
||||
for _, b := range a {
|
||||
sumBytes += int(b - 48)
|
||||
}
|
||||
fmt.Printf("\nblocks %c, cells %d\n", a, le)
|
||||
if le-sumBytes <= 0 {
|
||||
fmt.Println("No solution")
|
||||
return
|
||||
}
|
||||
prep := make([]string, len(a))
|
||||
for i, b := range a {
|
||||
prep[i] = strings.Repeat("1", int(b-48))
|
||||
}
|
||||
for _, r := range genSequence(prep, le-sumBytes+1) {
|
||||
fmt.Println(r[1:])
|
||||
}
|
||||
}
|
||||
|
||||
func genSequence(ones []string, numZeros int) []string {
|
||||
if len(ones) == 0 {
|
||||
return []string{strings.Repeat("0", numZeros)}
|
||||
}
|
||||
var result []string
|
||||
for x := 1; x < numZeros-len(ones)+2; x++ {
|
||||
skipOne := ones[1:]
|
||||
for _, tail := range genSequence(skipOne, numZeros-x) {
|
||||
result = append(result, strings.Repeat("0", x)+ones[0]+tail)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func main() {
|
||||
printBlock("21", 5)
|
||||
printBlock("", 5)
|
||||
printBlock("8", 10)
|
||||
printBlock("2323", 15)
|
||||
printBlock("23", 5)
|
||||
}
|
||||
7
Task/Nonoblock/J/nonoblock-1.j
Normal file
7
Task/Nonoblock/J/nonoblock-1.j
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
nonoblock=:4 :0
|
||||
s=. 1+(1+x)-+/1+y
|
||||
pad=.1+(#~ s >+/"1)((1+#y)#s) #: i.s^1+#y
|
||||
~.pad (_1}.1 }. ,. #&, 0 ,. 1 + i.@#@])"1]y,0
|
||||
)
|
||||
|
||||
neat=: [: (#~ # $ 0 1"_)@": {&(' ',65}.a.)&.>
|
||||
27
Task/Nonoblock/J/nonoblock-2.j
Normal file
27
Task/Nonoblock/J/nonoblock-2.j
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
neat 5 nonoblock 2 1
|
||||
│A│A│ │B│ │
|
||||
│A│A│ │ │B│
|
||||
│ │A│A│ │B│
|
||||
neat 5 nonoblock ''
|
||||
│ │ │ │ │ │
|
||||
neat 10 nonoblock 8
|
||||
│A│A│A│A│A│A│A│A│ │ │
|
||||
│ │A│A│A│A│A│A│A│A│ │
|
||||
│ │ │A│A│A│A│A│A│A│A│
|
||||
neat 15 nonoblock 2 3 2 3
|
||||
│A│A│ │B│B│B│ │C│C│ │D│D│D│ │ │
|
||||
│A│A│ │B│B│B│ │C│C│ │ │D│D│D│ │
|
||||
│A│A│ │B│B│B│ │C│C│ │ │ │D│D│D│
|
||||
│A│A│ │B│B│B│ │ │C│C│ │D│D│D│ │
|
||||
│A│A│ │B│B│B│ │ │C│C│ │ │D│D│D│
|
||||
│A│A│ │B│B│B│ │ │ │C│C│ │D│D│D│
|
||||
│A│A│ │ │B│B│B│ │C│C│ │D│D│D│ │
|
||||
│A│A│ │ │B│B│B│ │C│C│ │ │D│D│D│
|
||||
│A│A│ │ │B│B│B│ │ │C│C│ │D│D│D│
|
||||
│A│A│ │ │ │B│B│B│ │C│C│ │D│D│D│
|
||||
│ │A│A│ │B│B│B│ │C│C│ │D│D│D│ │
|
||||
│ │A│A│ │B│B│B│ │C│C│ │ │D│D│D│
|
||||
│ │A│A│ │B│B│B│ │ │C│C│ │D│D│D│
|
||||
│ │A│A│ │ │B│B│B│ │C│C│ │D│D│D│
|
||||
│ │ │A│A│ │B│B│B│ │C│C│ │D│D│D│
|
||||
neat 5 nonoblock 2 3
|
||||
53
Task/Nonoblock/Java/nonoblock.java
Normal file
53
Task/Nonoblock/Java/nonoblock.java
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import java.util.*;
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
public class Nonoblock {
|
||||
|
||||
public static void main(String[] args) {
|
||||
printBlock("21", 5);
|
||||
printBlock("", 5);
|
||||
printBlock("8", 10);
|
||||
printBlock("2323", 15);
|
||||
printBlock("23", 5);
|
||||
}
|
||||
|
||||
static void printBlock(String data, int len) {
|
||||
int sumChars = data.chars().map(c -> Character.digit(c, 10)).sum();
|
||||
String[] a = data.split("");
|
||||
|
||||
System.out.printf("%nblocks %s, cells %s%n", Arrays.toString(a), len);
|
||||
if (len - sumChars <= 0) {
|
||||
System.out.println("No solution");
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> prep = stream(a).filter(x -> !"".equals(x))
|
||||
.map(x -> repeat(Character.digit(x.charAt(0), 10), "1"))
|
||||
.collect(toList());
|
||||
|
||||
for (String r : genSequence(prep, len - sumChars + 1))
|
||||
System.out.println(r.substring(1));
|
||||
}
|
||||
|
||||
// permutation generator, translated from Python via D
|
||||
static List<String> genSequence(List<String> ones, int numZeros) {
|
||||
if (ones.isEmpty())
|
||||
return Arrays.asList(repeat(numZeros, "0"));
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
for (int x = 1; x < numZeros - ones.size() + 2; x++) {
|
||||
List<String> skipOne = ones.stream().skip(1).collect(toList());
|
||||
for (String tail : genSequence(skipOne, numZeros - x))
|
||||
result.add(repeat(x, "0") + ones.get(0) + tail);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static String repeat(int n, String s) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < n; i++)
|
||||
sb.append(s);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
61
Task/Nonoblock/JavaScript/nonoblock.js
Normal file
61
Task/Nonoblock/JavaScript/nonoblock.js
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
const compose = (...fn) => (...x) => fn.reduce((a, b) => c => a(b(c)))(...x);
|
||||
const inv = b => !b;
|
||||
const arrJoin = str => arr => arr.join(str);
|
||||
const mkArr = (l, f) => Array(l).fill(f);
|
||||
const sumArr = arr => arr.reduce((a, b) => a + b, 0);
|
||||
const sumsTo = val => arr => sumArr(arr) === val;
|
||||
const zipper = arr => (p, c, i) => arr[i] ? [...p, c, arr[i]] : [...p, c];
|
||||
const zip = (a, b) => a.reduce(zipper(b), []);
|
||||
const zipArr = arr => a => zip(a, arr);
|
||||
const hasInner = v => arr => arr.slice(1, -1).indexOf(v) >= 0;
|
||||
const choose = (even, odd) => n => n % 2 === 0 ? even : odd;
|
||||
const toBin = f => arr => arr.reduce(
|
||||
(p, c, i) => [...p, ...mkArr(c, f(i))], []);
|
||||
|
||||
|
||||
const looper = (arr, max, acc = [[...arr]], idx = 0) => {
|
||||
if (idx !== arr.length) {
|
||||
const b = looper([...arr], max, acc, idx + 1)[0];
|
||||
if (b[idx] !== max) {
|
||||
b[idx] = b[idx] + 1;
|
||||
acc.push(looper([...b], max, acc, idx)[0]);
|
||||
}
|
||||
}
|
||||
return [arr, acc];
|
||||
};
|
||||
|
||||
const gapPerms = (grpSize, numGaps, minVal = 0) => {
|
||||
const maxVal = numGaps - grpSize * minVal + minVal;
|
||||
return maxVal <= 0
|
||||
? (grpSize === 2 ? [[0]] : [])
|
||||
: looper(mkArr(grpSize, minVal), maxVal)[1];
|
||||
}
|
||||
|
||||
const test = (cells, ...blocks) => {
|
||||
const grpSize = blocks.length + 1;
|
||||
const numGaps = cells - sumArr(blocks);
|
||||
|
||||
// Filter functions
|
||||
const sumsToTrg = sumsTo(numGaps);
|
||||
const noInnerZero = compose(inv, hasInner(0));
|
||||
|
||||
// Output formatting
|
||||
const combine = zipArr([...blocks]);
|
||||
const choices = toBin(choose(0, 1));
|
||||
const output = compose(console.log, arrJoin(''), choices, combine);
|
||||
|
||||
console.log(`\n${cells} cells. Blocks: ${blocks}`);
|
||||
gapPerms(grpSize, numGaps)
|
||||
.filter(noInnerZero)
|
||||
.filter(sumsToTrg)
|
||||
.map(output);
|
||||
};
|
||||
|
||||
test(5, 2, 1);
|
||||
test(5);
|
||||
test(5, 5);
|
||||
test(5, 1, 1, 1);
|
||||
test(10, 8);
|
||||
test(15, 2, 3, 2, 3);
|
||||
test(10, 4, 3);
|
||||
test(5, 2, 3);
|
||||
36
Task/Nonoblock/Julia/nonoblock.julia
Normal file
36
Task/Nonoblock/Julia/nonoblock.julia
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
minsized(arr) = join(map(x->"#"^x, arr), ".")
|
||||
minlen(arr) = sum(arr) + length(arr) - 1
|
||||
|
||||
function sequences(blockseq, numblanks)
|
||||
if isempty(blockseq)
|
||||
return ["." ^ numblanks]
|
||||
elseif minlen(blockseq) == numblanks
|
||||
return minsized(blockseq)
|
||||
else
|
||||
result = Vector{String}()
|
||||
allbuthead = blockseq[2:end]
|
||||
for leftspace in 0:(numblanks - minlen(blockseq))
|
||||
header = "." ^ leftspace * "#" ^ blockseq[1] * "."
|
||||
rightspace = numblanks - length(header)
|
||||
if isempty(allbuthead)
|
||||
push!(result, rightspace <= 0 ? header[1:numblanks] : header * "." ^ rightspace)
|
||||
elseif minlen(allbuthead) == rightspace
|
||||
push!(result, header * minsized(allbuthead))
|
||||
else
|
||||
map(x -> push!(result, header * x), sequences(allbuthead, rightspace))
|
||||
end
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
function nonoblocks(bvec, len)
|
||||
println("With blocks $bvec and $len cells:")
|
||||
len < minlen(bvec) ? println("No solution") : for seq in sequences(bvec, len) println(seq) end
|
||||
end
|
||||
|
||||
nonoblocks([2, 1], 5)
|
||||
nonoblocks(Vector{Int}([]), 5)
|
||||
nonoblocks([8], 10)
|
||||
nonoblocks([2, 3, 2, 3], 15)
|
||||
nonoblocks([2, 3], 5)
|
||||
33
Task/Nonoblock/Kotlin/nonoblock.kotlin
Normal file
33
Task/Nonoblock/Kotlin/nonoblock.kotlin
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// version 1.2.0
|
||||
|
||||
fun printBlock(data: String, len: Int) {
|
||||
val a = data.toCharArray()
|
||||
val sumChars = a.map { it.toInt() - 48 }.sum()
|
||||
println("\nblocks ${a.asList()}, cells $len")
|
||||
if (len - sumChars <= 0) {
|
||||
println("No solution")
|
||||
return
|
||||
}
|
||||
val prep = a.map { "1".repeat(it.toInt() - 48) }
|
||||
for (r in genSequence(prep, len - sumChars + 1)) println(r.substring(1))
|
||||
}
|
||||
|
||||
fun genSequence(ones: List<String>, numZeros: Int): List<String> {
|
||||
if (ones.isEmpty()) return listOf("0".repeat(numZeros))
|
||||
val result = mutableListOf<String>()
|
||||
for (x in 1 until numZeros - ones.size + 2) {
|
||||
val skipOne = ones.drop(1)
|
||||
for (tail in genSequence(skipOne, numZeros - x)) {
|
||||
result.add("0".repeat(x) + ones[0] + tail)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
printBlock("21", 5)
|
||||
printBlock("", 5)
|
||||
printBlock("8", 10)
|
||||
printBlock("2323", 15)
|
||||
printBlock("23", 5)
|
||||
}
|
||||
47
Task/Nonoblock/Lua/nonoblock.lua
Normal file
47
Task/Nonoblock/Lua/nonoblock.lua
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
local examples = {
|
||||
{5, {2, 1}},
|
||||
{5, {}},
|
||||
{10, {8}},
|
||||
{15, {2, 3, 2, 3}},
|
||||
{5, {2, 3}},
|
||||
}
|
||||
|
||||
function deep (blocks, iBlock, freedom, str)
|
||||
if iBlock == #blocks then -- last
|
||||
for takenFreedom = 0, freedom do
|
||||
print (str..string.rep("0", takenFreedom) .. string.rep("1", blocks[iBlock]) .. string.rep("0", freedom - takenFreedom))
|
||||
total = total + 1
|
||||
end
|
||||
else
|
||||
for takenFreedom = 0, freedom do
|
||||
local str2 = str..string.rep("0", takenFreedom) .. string.rep("1", blocks[iBlock]) .. "0"
|
||||
deep (blocks, iBlock+1, freedom-takenFreedom, str2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function main (cells, blocks) -- number, list
|
||||
local str = " "
|
||||
print (cells .. ' cells and {' .. table.concat(blocks, ', ') .. '} blocks')
|
||||
local freedom = cells - #blocks + 1 -- freedom
|
||||
for iBlock = 1, #blocks do
|
||||
freedom = freedom - blocks[iBlock]
|
||||
end
|
||||
if #blocks == 0 then
|
||||
print ('no blocks')
|
||||
print (str..string.rep("0", cells))
|
||||
total = 1
|
||||
elseif freedom < 0 then
|
||||
print ('no solutions')
|
||||
else
|
||||
print ('Possibilities:')
|
||||
deep (blocks, 1, freedom, str)
|
||||
end
|
||||
end
|
||||
|
||||
for i, example in ipairs (examples) do
|
||||
print ("\n--")
|
||||
total = 0
|
||||
main (example[1], example[2])
|
||||
print ('A total of ' .. total .. ' possible configurations.')
|
||||
end
|
||||
55
Task/Nonoblock/M2000-Interpreter/nonoblock-1.m2000
Normal file
55
Task/Nonoblock/M2000-Interpreter/nonoblock-1.m2000
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
Module NonoBlock {
|
||||
Form 80,40
|
||||
Flush
|
||||
Print "Nonoblock"
|
||||
Data 5, (2, 1)
|
||||
Data 5, (,)
|
||||
Data 10, (8,)
|
||||
Data 15, (2,3,2,3)
|
||||
Data 5, (2,3)
|
||||
Def BLen(a$)=(Len(a$)-1)/2
|
||||
Function UseLetter(arr) {
|
||||
Dim Base 0, Res$(Len(arr))
|
||||
Link Res$() to Res()
|
||||
Def Ord$(a$)=ChrCode$(Chrcode(a$)+1)
|
||||
L$="A"
|
||||
i=each(arr)
|
||||
While i {
|
||||
Res$(i^)=String$("|"+L$, Array(i))+"|"
|
||||
L$=Ord$(L$)
|
||||
}
|
||||
=Res()
|
||||
}
|
||||
Count=0
|
||||
For i=1 to 5
|
||||
Read Cells, Blocks
|
||||
Blocks=UseLetter(Blocks)
|
||||
Print str$(i,"")+".", "Cells=";Cells, "", iF(len(Blocks)=0->("Empty",), Blocks)
|
||||
PrintRow( "|", Cells, Blocks, &Count)
|
||||
CheckCount()
|
||||
Next I
|
||||
Sub CheckCount()
|
||||
If count=0 Then Print " Impossible"
|
||||
count=0
|
||||
End Sub
|
||||
Sub PrintRow(Lpart$, Cells, Blocks, &Comp)
|
||||
If len(Blocks)=0 Then Comp++ :Print Format$("{0::-3} {1}", Comp, lpart$+String$("_|", Cells)): Exit Sub
|
||||
If Cells<=0 Then Exit Sub
|
||||
Local TotalBlocksLength=0, Sep_Spaces=-1
|
||||
Local Block=Each(Blocks), block$
|
||||
While Block {
|
||||
Block$=Array$(Block)
|
||||
TotalBlocksLength+=Blen(Block$)
|
||||
Sep_Spaces++
|
||||
}
|
||||
Local MaxLengthNeed=TotalBlocksLength+Sep_Spaces
|
||||
If MaxLengthNeed>Cells Then Exit Sub
|
||||
block$=Array$(Car(Blocks))
|
||||
local temp=Blen(block$)
|
||||
block$=Mid$(Block$, 2)
|
||||
If Len(Blocks)>1 Then block$+="_|" :temp++
|
||||
PrintRow(Lpart$+block$, Cells-temp, Cdr(Blocks), &Comp)
|
||||
PrintRow(lpart$+String$("_|", 1), Cells-1,Blocks, &Comp)
|
||||
End Sub
|
||||
}
|
||||
NonoBlock
|
||||
90
Task/Nonoblock/M2000-Interpreter/nonoblock-2.m2000
Normal file
90
Task/Nonoblock/M2000-Interpreter/nonoblock-2.m2000
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
Module Nonoblock (n, m) {
|
||||
Print "Cells:",n," Blocks:",m
|
||||
Dim n(1 to n), m(1 to m), sp(1 to m*2), sk(1 to m*2), part(1 to m)
|
||||
queue=0
|
||||
If m>0 Then {
|
||||
Print "Block Size:",
|
||||
For i=1 to m {
|
||||
Read m(i)
|
||||
Print m(i),
|
||||
}
|
||||
Print
|
||||
part(m)=m(m)
|
||||
If m>1 Then {
|
||||
For i=m-1 to 1 {
|
||||
part(i)=m(i)+part(i+1)+1
|
||||
}
|
||||
}
|
||||
}
|
||||
If part(1)>n Then {
|
||||
Print "Impossible"
|
||||
} Else {
|
||||
p1=0
|
||||
l=0
|
||||
Counter=0
|
||||
While p1<=n-part(1) {
|
||||
k=0
|
||||
p=p1+1
|
||||
For i=1 to n {
|
||||
n(i)=0
|
||||
}
|
||||
flag=True
|
||||
Repeat {
|
||||
While k<m {
|
||||
k++
|
||||
l=0
|
||||
While l<m(k) and p<=n {
|
||||
l++
|
||||
n(p)=1
|
||||
p++
|
||||
}
|
||||
If p<n Then {
|
||||
n(p)=0
|
||||
p++
|
||||
If k<m Then {
|
||||
If p+part(k+1)<n+1 Then {
|
||||
queue++
|
||||
sp(queue)=p
|
||||
sk(queue)=k
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
flag=True
|
||||
If l=m(k) Then {
|
||||
counter++
|
||||
Print Str$(counter,"0000 ");
|
||||
For i=1 to n {
|
||||
Print n(i);" ";
|
||||
}
|
||||
Print
|
||||
If queue>0 Then {
|
||||
p=sp(queue)
|
||||
k=sk(queue)
|
||||
queue--
|
||||
For i=p to n {
|
||||
n(i)=0
|
||||
}
|
||||
p++
|
||||
If k<m Then {
|
||||
If p+part(k+1)<n+1 Then {
|
||||
queue++
|
||||
sp(queue)=p
|
||||
' sk(queue)=k
|
||||
}
|
||||
}
|
||||
flag=False
|
||||
}
|
||||
}
|
||||
} Until flag
|
||||
p1++
|
||||
If k=0 Then Exit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Nonoblock 5,2,2,1
|
||||
Nonoblock 5,0
|
||||
Nonoblock 10,1,8
|
||||
Nonoblock 15,4,2,3,2,3
|
||||
Nonoblock 5,2,3,2
|
||||
22
Task/Nonoblock/Mathematica/nonoblock.math
Normal file
22
Task/Nonoblock/Mathematica/nonoblock.math
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
ClearAll[SpacesDistributeOverN, Possibilities]
|
||||
SpacesDistributeOverN[s_, p_] :=
|
||||
Flatten[
|
||||
Permutations /@ (Join[#, ConstantArray[0, p - Length[#]]] & /@
|
||||
IntegerPartitions[s, p]), 1]
|
||||
Possibilities[hint_, len_] :=
|
||||
Module[{p = hint, l = len, b = Length[hint], Spaces, out},
|
||||
Spaces = # + (Prepend[Append[ConstantArray[1, b - 1], 0],
|
||||
0]) & /@ (SpacesDistributeOverN[l - Total@p - (b - 1), b + 1]);
|
||||
out = Flatten /@ (
|
||||
Riffle[#, Map[Table[1, {#}] &, p, {1}]] & /@
|
||||
Map[Table[0, {#}] &, Spaces, {2}]);
|
||||
StringJoin @@@ (out /. {0 -> ".", 1 -> "#"})
|
||||
]
|
||||
Possibilities[{}, len_] := Module[{},
|
||||
{StringJoin[ConstantArray[".", len]]}
|
||||
]
|
||||
Possibilities[{2, 1}, 5]
|
||||
Possibilities[{}, 5]
|
||||
Possibilities[{8}, 10]
|
||||
Possibilities[{2, 3, 2, 3}, 15]
|
||||
Possibilities[{2, 3}, 5]
|
||||
34
Task/Nonoblock/Nim/nonoblock.nim
Normal file
34
Task/Nonoblock/Nim/nonoblock.nim
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import math, sequtils, strformat, strutils
|
||||
|
||||
|
||||
proc genSequence(ones: seq[string]; numZeroes: Natural): seq[string] =
|
||||
if ones.len == 0: return @[repeat('0', numZeroes)]
|
||||
for x in 1..(numZeroes - ones.len + 1):
|
||||
let skipOne = ones[1..^1]
|
||||
for tail in genSequence(skipOne, numZeroes - x):
|
||||
result.add repeat('0', x) & ones[0] & tail
|
||||
|
||||
|
||||
proc printBlock(data: string; length: Positive) =
|
||||
|
||||
let a = mapIt(data, ord(it) - ord('0'))
|
||||
let sumBytes = sum(a)
|
||||
|
||||
echo &"\nblocks {($a)[1..^1]} cells {length}"
|
||||
if length - sumBytes <= 0:
|
||||
echo "No solution"
|
||||
return
|
||||
|
||||
var prep: seq[string]
|
||||
for b in a: prep.add repeat('1', b)
|
||||
|
||||
for r in genSequence(prep, length - sumBytes + 1):
|
||||
echo r[1..^1]
|
||||
|
||||
|
||||
when isMainModule:
|
||||
printBlock("21", 5)
|
||||
printBlock("", 5)
|
||||
printBlock("8", 10)
|
||||
printBlock("2323", 15)
|
||||
printBlock("23", 5)
|
||||
101
Task/Nonoblock/Pascal/nonoblock.pas
Normal file
101
Task/Nonoblock/Pascal/nonoblock.pas
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
program Nonoblock;
|
||||
uses SysUtils;
|
||||
|
||||
// Working through solutions to the problem:
|
||||
// Fill an array z[] with non-negative integers
|
||||
// whose sum is the passed-in integer s.
|
||||
function GetFirstSolution( var z : array of integer;
|
||||
s : integer) : boolean;
|
||||
var
|
||||
j : integer;
|
||||
begin
|
||||
result := (s >= 0) and (High(z) >= 0); // failed if s < 0 or array is empty
|
||||
if result then begin // else initialize to solution 0, ..., 0, s
|
||||
j := High(z); z[j] := s;
|
||||
while (j > 0) do begin
|
||||
dec(j); z[j] := 0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Next solution: return true for success, false if no more solutions.
|
||||
// Solutions are generated in lexicographic order.
|
||||
function GetNextSolution( var z : array of integer) : boolean;
|
||||
var
|
||||
h, j : integer;
|
||||
begin
|
||||
h := High(z);
|
||||
j := h; // find highest index j such that z[j] > 0.
|
||||
while (j > 0) and (z[j] = 0) do dec(j);
|
||||
result := (j > 0); // if index is 0, or there is no such index, failed
|
||||
if result then begin // else update caller's array to give next solution
|
||||
inc(z[j - 1]);
|
||||
z[h] := z[j] - 1;
|
||||
if (j < h) then z[j] := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Procedure to print solutions to nonoblock task on RosettaCode
|
||||
procedure PrintSolutions( nrCells : integer;
|
||||
blockSizes : array of integer);
|
||||
const // cosmetic
|
||||
MARGIN = 4;
|
||||
GAP_CHAR = '.';
|
||||
BLOCK_CHAR = '#';
|
||||
var
|
||||
sb : SysUtils.TStringBuilder;
|
||||
nrBlocks, blockSum, gapSum : integer;
|
||||
gapSizes : array of integer;
|
||||
i, nrSolutions : integer;
|
||||
begin
|
||||
nrBlocks := Length( blockSizes);
|
||||
|
||||
// Print a title, showing the number of cells and the block sizes
|
||||
sb := SysUtils.TStringBuilder.Create();
|
||||
sb.AppendFormat('%d cells; blocks [', [nrCells]);
|
||||
for i := 0 to nrBlocks - 1 do begin
|
||||
if (i > 0) then sb.Append(',');
|
||||
sb.Append( blockSizes[i]);
|
||||
end;
|
||||
sb.Append(']');
|
||||
WriteLn( sb.ToString());
|
||||
|
||||
blockSum := 0; // total of block sizes
|
||||
for i := 0 to nrBlocks - 1 do inc( blockSum, blockSizes[i]);
|
||||
|
||||
gapSum := nrCells - blockSum;
|
||||
// Except in the trivial case of no blocks,
|
||||
// we reduce the size of each inner gap by 1.
|
||||
if nrBlocks > 0 then dec( gapSum, nrBlocks - 1);
|
||||
|
||||
// Work through all solutions and print them nicely.
|
||||
nrSolutions := 0;
|
||||
SetLength( gapSizes, nrBlocks + 1); // include the gap at each end
|
||||
if GetFirstSolution( gapSizes, gapSum) then begin
|
||||
repeat
|
||||
inc( nrSolutions);
|
||||
sb.Clear();
|
||||
sb.Append( ' ', MARGIN);
|
||||
for i := 0 to nrBlocks - 1 do begin
|
||||
sb.Append( GAP_CHAR, gapSizes[i]);
|
||||
// We reduced the inner gaps by 1; now we restore the deleted char.
|
||||
if (i > 0) then sb.Append( GAP_CHAR);
|
||||
sb.Append( BLOCK_CHAR, blockSizes[i]);
|
||||
end;
|
||||
sb.Append( GAP_CHAR, gapSizes[nrBlocks]);
|
||||
WriteLn( sb.ToString());
|
||||
until not GetNextSolution( gapSizes);
|
||||
end;
|
||||
sb.Free();
|
||||
WriteLn( SysUtils.Format( 'Number of solutions = %d', [nrSolutions]));
|
||||
WriteLn('');
|
||||
end;
|
||||
|
||||
// Main program
|
||||
begin
|
||||
PrintSolutions( 5, [2,1]);
|
||||
PrintSolutions( 5, []);
|
||||
PrintSolutions( 10, [8]);
|
||||
PrintSolutions( 15, [2,3,2,3]);
|
||||
PrintSolutions( 5, [2,3]);
|
||||
end.
|
||||
20
Task/Nonoblock/Perl/nonoblock.pl
Normal file
20
Task/Nonoblock/Perl/nonoblock.pl
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
|
||||
while( <DATA> )
|
||||
{
|
||||
print "\n$_", tr/\n/=/cr;
|
||||
my ($cells, @blocks) = split;
|
||||
my $letter = 'A';
|
||||
$_ = join '.', map { $letter++ x $_ } @blocks;
|
||||
$cells < length and print("no solution\n"), next;
|
||||
$_ .= '.' x ($cells - length) . "\n";
|
||||
1 while print, s/^(\.*)\b(.*?)\b(\w+)\.\B/$2$1.$3/;
|
||||
}
|
||||
|
||||
__DATA__
|
||||
5 2 1
|
||||
5
|
||||
10 8
|
||||
15 2 3 2 3
|
||||
5 2 3
|
||||
51
Task/Nonoblock/Phix/nonoblock.phix
Normal file
51
Task/Nonoblock/Phix/nonoblock.phix
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">nobr</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">neat</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">ni</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">blocks</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">blocks</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">neat</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">blocks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">blocks</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">blocks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #000000;">blocks</span><span style="color: #0000FF;">)+</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">blocks</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">neat</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">-</span><span style="color: #000000;">b</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">ni</span> <span style="color: #008080;">to</span> <span style="color: #000000;">e</span> <span style="color: #008080;">by</span> <span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span> <span style="color: #008080;">to</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">b</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span> <span style="color: #008080;">by</span> <span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">neat</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nobr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">neat</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">b</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">blocks</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">neat</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: #008000;">' '</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">nonoblock</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">len</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">blocks</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">neat</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"|"</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len</span><span style="color: #0000FF;">),</span><span style="color: #008000;">'|'</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">"|"</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">nobr</span><span style="color: #0000FF;">({},</span><span style="color: #000000;">neat</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">blocks</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,{}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">}}}</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">len</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">blocks</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">res</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;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">len</span><span style="color: #0000FF;">,</span><span style="color: #000000;">blocks</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d cells with blocks %s"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">len</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">blocks</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;">"%s\n%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'='</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">))})</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nonoblock</span><span style="color: #0000FF;">(</span><span style="color: #000000;">len</span><span style="color: #0000FF;">,</span><span style="color: #000000;">blocks</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</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;">"No solutions.\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">ri</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;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</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;">"%3d: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">]})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</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;">"\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
52
Task/Nonoblock/Python/nonoblock.py
Normal file
52
Task/Nonoblock/Python/nonoblock.py
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
def nonoblocks(blocks, cells):
|
||||
if not blocks or blocks[0] == 0:
|
||||
yield [(0, 0)]
|
||||
else:
|
||||
assert sum(blocks) + len(blocks)-1 <= cells, \
|
||||
'Those blocks will not fit in those cells'
|
||||
blength, brest = blocks[0], blocks[1:] # Deal with the first block of length
|
||||
minspace4rest = sum(1+b for b in brest) # The other blocks need space
|
||||
# Slide the start position from left to max RH index allowing for other blocks.
|
||||
for bpos in range(0, cells - minspace4rest - blength + 1):
|
||||
if not brest:
|
||||
# No other blocks to the right so just yield this one.
|
||||
yield [(bpos, blength)]
|
||||
else:
|
||||
# More blocks to the right so create a *sub-problem* of placing
|
||||
# the brest blocks in the cells one space to the right of the RHS of
|
||||
# this block.
|
||||
offset = bpos + blength +1
|
||||
nonoargs = (brest, cells - offset) # Pre-compute arguments to nonoargs
|
||||
# recursive call to nonoblocks yields multiple sub-positions
|
||||
for subpos in nonoblocks(*nonoargs):
|
||||
# Remove the offset from sub block positions
|
||||
rest = [(offset + bp, bl) for bp, bl in subpos]
|
||||
# Yield this block plus sub blocks positions
|
||||
vec = [(bpos, blength)] + rest
|
||||
yield vec
|
||||
|
||||
def pblock(vec, cells):
|
||||
'Prettyprints each run of blocks with a different letter A.. for each block of filled cells'
|
||||
vector = ['_'] * cells
|
||||
for ch, (bp, bl) in enumerate(vec, ord('A')):
|
||||
for i in range(bp, bp + bl):
|
||||
vector[i] = chr(ch) if vector[i] == '_' else'?'
|
||||
return '|' + '|'.join(vector) + '|'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for blocks, cells in (
|
||||
([2, 1], 5),
|
||||
([], 5),
|
||||
([8], 10),
|
||||
([2, 3, 2, 3], 15),
|
||||
# ([4, 3], 10),
|
||||
# ([2, 1], 5),
|
||||
# ([3, 1], 10),
|
||||
([2, 3], 5),
|
||||
):
|
||||
print('\nConfiguration:\n %s # %i cells and %r blocks' % (pblock([], cells), cells, blocks))
|
||||
print(' Possibilities:')
|
||||
for i, vector in enumerate(nonoblocks(blocks, cells)):
|
||||
print(' ', pblock(vector, cells))
|
||||
print(' A total of %i Possible configurations.' % (i+1))
|
||||
53
Task/Nonoblock/REXX/nonoblock.rexx
Normal file
53
Task/Nonoblock/REXX/nonoblock.rexx
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*REXX program enumerates all possible configurations (or an error) for nonogram puzzles*/
|
||||
$.=; $.1= 5 2 1
|
||||
$.2= 5
|
||||
$.3= 10 8
|
||||
$.4= 15 2 3 2 3
|
||||
$.5= 5 2 3
|
||||
do i=1 while $.i\==''
|
||||
parse var $.i N blocks /*obtain N and blocks from array. */
|
||||
N= strip(N); blocks= space(blocks) /*assign stripped N and blocks. */
|
||||
call nono /*incoke NONO subroutine for heavy work*/
|
||||
end /*i*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
nono: say copies('=', 70) /*display seperator for title.*/
|
||||
say 'For ' N " cells and blocks of: " blocks /*display the title for output*/
|
||||
z= /*assign starter value for Z. */
|
||||
do w=1 for words(blocks) /*process each of the blocks. */
|
||||
z= z copies('#', word(blocks,w) ) /*build a string for 1st value*/
|
||||
end /*w*/ /*Z now has a leading blank. */
|
||||
#= 1 /*number of positions (so far)*/
|
||||
z= translate( strip(z), ., ' '); L= length(z) /*change blanks to periods. */
|
||||
if L>N then do; say '***error*** invalid blocks for number of cells.'; return
|
||||
end
|
||||
@.0=; @.1= z; !.=0 /*assign default and the first position*/
|
||||
z= pad(z) /*fill─out (pad) the value with periods*/
|
||||
|
||||
do prepend=1 while words(blocks)\==0 /*process all the positions (leading .)*/
|
||||
new= . || @.prepend /*create positions with leading dots. */
|
||||
if length(new)>N then leave /*Length is too long? Then stop adding*/
|
||||
call add /*add position that has a leading dot. */
|
||||
end /*prepend*/ /* [↑] prepend positions with dots. */
|
||||
|
||||
do k=1 for N /*process each of the positions so far.*/
|
||||
do c=1 for N /* " " " " position blocks. */
|
||||
if @.c=='' then iterate /*if string is null, skip the string. */
|
||||
p= loc(@.c, k) /*find location of block in position. */
|
||||
if p==0 | p>=N then iterate /*Location zero or out─of─range? Skip.*/
|
||||
new= strip( insert(., @.c, p),'T',.) /*insert a dot and strip trailing dots.*/
|
||||
if strip(new,'T',.)=@.c then iterate /*Is it the same value? Then skip it. */
|
||||
if length(new)<=N then call add /*Is length OK? Then add position. */
|
||||
end /*k*/
|
||||
end /*c*/
|
||||
say
|
||||
say '─position─' center("value", max(7, length(z) ), '─') /*show hdr for output.*/
|
||||
|
||||
do m=1 for #
|
||||
say center(m, 10) pad(@.m) /*display the index count and position.*/
|
||||
end /*m*/
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
loc: _=0; do arg(2); _=pos('#.',pad(arg(1)),_+1); if _==0 then return 0; end; return _+1
|
||||
add: if !.new==1 then return; #= # + 1; @.#= new; !.new=1; return
|
||||
pad: return left( arg(1), N, .)
|
||||
65
Task/Nonoblock/Racket/nonoblock.rkt
Normal file
65
Task/Nonoblock/Racket/nonoblock.rkt
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#lang racket
|
||||
(require racket/trace)
|
||||
|
||||
(define add1-to-car (match-lambda [(cons (app add1 p1) t) (cons p1 t)]))
|
||||
|
||||
;; inputs:
|
||||
;; cells -- available cells
|
||||
;; blocks -- list of block widths
|
||||
;; output:
|
||||
;; gap-block+gaps
|
||||
;; where gap-block+gaps is:
|
||||
;; (list gap) -- a single gap
|
||||
;; (list gap block-width gap-block+gaps) -- padding to left, a block, right hand side
|
||||
(define (nonoblock cells blocks)
|
||||
(match* ((- cells (apply + (length blocks) -1 blocks)) #| padding available on both sides |# blocks)
|
||||
[(_ (list)) (list (list cells))] ; generates an empty list of padding
|
||||
|
||||
[((? negative?) _) null] ; impossible to satisfy
|
||||
|
||||
[((and avp
|
||||
;; use add1 with in-range because we actually want from 0 to available-padding
|
||||
;; without add1, in-range iterates from 0 to (available-padding - 1)
|
||||
(app add1 avp+1))
|
||||
(list block))
|
||||
(for/list ((l-pad (in-range 0 avp+1)))
|
||||
(define r-pad (- avp l-pad)) ; what remains goes to right
|
||||
(list l-pad block r-pad))]
|
||||
|
||||
[((app add1 avp+1) (list block more-blocks ...))
|
||||
(for*/list ((l-pad (in-range 0 avp+1))
|
||||
(cells-- (in-value (- cells block l-pad 1)))
|
||||
(r-blocks (in-value (nonoblock cells-- more-blocks)))
|
||||
(r-block (in-list r-blocks)))
|
||||
(list* l-pad block (add1-to-car r-block)))])) ; put a single space pad on left of r-block
|
||||
|
||||
(define (neat rslt)
|
||||
(define dots (curryr make-string #\.))
|
||||
(define Xes (curryr make-string #\X))
|
||||
(define inr
|
||||
(match-lambda
|
||||
[(list 0 (app Xes b) t ...)
|
||||
(string-append b (inr t))]
|
||||
[(list (app dots p) (app Xes b) t ...)
|
||||
(string-append p b (inr t))]
|
||||
[(list (app dots p)) p]))
|
||||
(define (neat-row r)
|
||||
(string-append "|" (inr r) "|"))
|
||||
(string-join (map neat-row rslt) "\n"))
|
||||
|
||||
(define (tst c b)
|
||||
(define rslt (nonoblock c b))
|
||||
(define rslt-l (length rslt))
|
||||
(printf "~a cells, ~a blocks => ~a~%~a~%" c b
|
||||
(match rslt-l
|
||||
[0 "impossible"]
|
||||
[1 "1 solution"]
|
||||
[(app (curry format "~a solutions") r) r])
|
||||
(neat rslt)))
|
||||
|
||||
(module+ test
|
||||
(tst 5 '[2 1])
|
||||
(tst 5 '[])
|
||||
(tst 10 '[8])
|
||||
(tst 15 '[2 3 2 3])
|
||||
(tst 5 '[2 3]))
|
||||
9
Task/Nonoblock/Raku/nonoblock.raku
Normal file
9
Task/Nonoblock/Raku/nonoblock.raku
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
for (5, [2,1]), (5, []), (10, [8]), (5, [2,3]), (15, [2,3,2,3]) -> ($cells, @blocks) {
|
||||
say $cells, ' cells with blocks: ', @blocks ?? join ', ', @blocks !! '∅';
|
||||
my $letter = 'A';
|
||||
my $row = join '.', map { $letter++ x $_ }, @blocks;
|
||||
say "no solution\n" and next if $cells < $row.chars;
|
||||
say $row ~= '.' x $cells - $row.chars;
|
||||
say $row while $row ~~ s/^^ (\.*) <|w> (.*?) <|w> (\w+) \.<!|w> /$1$0.$2/;
|
||||
say '';
|
||||
}
|
||||
33
Task/Nonoblock/Ruby/nonoblock-1.rb
Normal file
33
Task/Nonoblock/Ruby/nonoblock-1.rb
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
def nonoblocks(cell, blocks)
|
||||
raise 'Those blocks will not fit in those cells' if cell < blocks.inject(0,:+) + blocks.size - 1
|
||||
nblock(cell, blocks, '', [])
|
||||
end
|
||||
|
||||
def nblock(cell, blocks, position, result)
|
||||
if cell <= 0
|
||||
result << position[0..cell-1]
|
||||
elsif blocks.empty? or blocks[0].zero?
|
||||
result << position + '.' * cell
|
||||
else
|
||||
rest = cell - blocks.inject(:+) - blocks.size + 2
|
||||
bl, *brest = blocks
|
||||
rest.times.inject(result) do |res, i|
|
||||
nblock(cell-i-bl-1, brest, position + '.'*i + '#'*bl + '.', res)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
conf = [[ 5, [2, 1]],
|
||||
[ 5, []],
|
||||
[10, [8]],
|
||||
[15, [2, 3, 2, 3]],
|
||||
[ 5, [2, 3]], ]
|
||||
conf.each do |cell, blocks|
|
||||
begin
|
||||
puts "#{cell} cells and #{blocks} blocks"
|
||||
result = nonoblocks(cell, blocks)
|
||||
puts result, result.size, ""
|
||||
rescue => e
|
||||
p e
|
||||
end
|
||||
end
|
||||
54
Task/Nonoblock/Ruby/nonoblock-2.rb
Normal file
54
Task/Nonoblock/Ruby/nonoblock-2.rb
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
class NonoBlock
|
||||
def initialize(cell, blocks)
|
||||
raise 'Those blocks will not fit in those cells' if cell < blocks.inject(0,:+) + blocks.size - 1
|
||||
@result = []
|
||||
nonoblocks(cell, blocks, '')
|
||||
end
|
||||
|
||||
def result(correct=true)
|
||||
correct ? @result.map(&:nonocell) : @result
|
||||
end
|
||||
|
||||
private
|
||||
def nonoblocks(cell, blocks, position)
|
||||
if cell <= 0
|
||||
@result << position[0..cell-1]
|
||||
elsif blocks.empty? or blocks[0].zero?
|
||||
@result << position + '.' * cell
|
||||
else
|
||||
rest = cell - blocks.inject(0,:+) - blocks.size + 2
|
||||
bl, *brest = blocks
|
||||
rest.times do |i|
|
||||
nonoblocks(cell-i-bl-1, brest, position + '.'*i + '#'*bl + '.')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class String
|
||||
def nonocell # "##.###..##" -> "|A|A|_|B|B|B|_|_|C|C|"
|
||||
chr = ('A'..'Z').each
|
||||
s = tr('.','_').gsub(/#+/){|sharp| chr.next * sharp.size}
|
||||
"|#{s.chars.join('|')}|"
|
||||
end
|
||||
end
|
||||
|
||||
if __FILE__ == $0
|
||||
conf = [[ 5, [2, 1]],
|
||||
[ 5, []],
|
||||
[10, [8]],
|
||||
[15, [2, 3, 2, 3]],
|
||||
[ 5, [2, 3]] ]
|
||||
conf.each do |cell, blocks|
|
||||
begin
|
||||
puts "Configuration:",
|
||||
"#{('.'*cell).nonocell} # #{cell} cells and #{blocks} blocks",
|
||||
"Possibilities:"
|
||||
result = NonoBlock.new(cell, blocks).result
|
||||
puts result,
|
||||
"A total of #{result.size} Possible configurations.", ""
|
||||
rescue => e
|
||||
p e
|
||||
end
|
||||
end
|
||||
end
|
||||
79
Task/Nonoblock/Rust/nonoblock.rust
Normal file
79
Task/Nonoblock/Rust/nonoblock.rust
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
struct Nonoblock {
|
||||
width: usize,
|
||||
config: Vec<usize>,
|
||||
spaces: Vec<usize>,
|
||||
}
|
||||
|
||||
impl Nonoblock {
|
||||
pub fn new(width: usize, config: Vec<usize>) -> Nonoblock {
|
||||
Nonoblock {
|
||||
width: width,
|
||||
config: config,
|
||||
spaces: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn solve(&mut self) -> Vec<Vec<i32>> {
|
||||
let mut output: Vec<Vec<i32>> = Vec::new();
|
||||
self.spaces = (0..self.config.len()).fold(Vec::new(), |mut s, i| {
|
||||
s.push(match i {
|
||||
0 => 0,
|
||||
_ => 1,
|
||||
});
|
||||
s
|
||||
});
|
||||
if self.spaces.iter().sum::<usize>() + self.config.iter().sum::<usize>() <= self.width {
|
||||
'finished: loop {
|
||||
match self.spaces.iter().enumerate().fold((0, vec![0; self.width]), |mut a, (i, s)| {
|
||||
(0..self.config[i]).for_each(|j| a.1[a.0 + j + *s] = 1 + i as i32);
|
||||
return (a.0 + self.config[i] + *s, a.1);
|
||||
}) {
|
||||
(_, out) => output.push(out),
|
||||
}
|
||||
let mut i: usize = 1;
|
||||
'calc: loop {
|
||||
let len = self.spaces.len();
|
||||
if i > len {
|
||||
break 'finished;
|
||||
} else {
|
||||
self.spaces[len - i] += 1
|
||||
}
|
||||
if self.spaces.iter().sum::<usize>() + self.config.iter().sum::<usize>() > self.width {
|
||||
self.spaces[len - i] = 1;
|
||||
i += 1;
|
||||
} else {
|
||||
break 'calc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut blocks = [
|
||||
Nonoblock::new(5, vec![2, 1]),
|
||||
Nonoblock::new(5, vec![]),
|
||||
Nonoblock::new(10, vec![8]),
|
||||
Nonoblock::new(15, vec![2, 3, 2, 3]),
|
||||
Nonoblock::new(5, vec![2, 3]),
|
||||
];
|
||||
|
||||
for block in blocks.iter_mut() {
|
||||
println!("{} cells and {:?} blocks", block.width, block.config);
|
||||
println!("{}",(0..block.width).fold(String::from("="), |a, _| a + "=="));
|
||||
let solutions = block.solve();
|
||||
if solutions.len() > 0 {
|
||||
for solution in solutions.iter() {
|
||||
println!("{}", solution.iter().fold(String::from("|"), |s, f| s + &match f {
|
||||
i if *i > 0 => (('A' as u8 + ((*i - 1) as u8) % 26) as char).to_string(),
|
||||
_ => String::from("_"),
|
||||
}+ "|"));
|
||||
}
|
||||
} else {
|
||||
println!("No solutions. ");
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
52
Task/Nonoblock/Swift/nonoblock.swift
Normal file
52
Task/Nonoblock/Swift/nonoblock.swift
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import Foundation
|
||||
|
||||
func nonoblock(cells: Int, blocks: [Int]) {
|
||||
print("\(cells) cells and blocks \(blocks):")
|
||||
let totalBlockSize = blocks.reduce(0, +)
|
||||
if cells < totalBlockSize + blocks.count - 1 {
|
||||
print("no solution")
|
||||
return
|
||||
}
|
||||
|
||||
func solve(cells: Int, index: Int, totalBlockSize: Int, offset: Int) {
|
||||
if index == blocks.count {
|
||||
count += 1
|
||||
print("\(String(format: "%2d", count)) \(String(output))")
|
||||
return
|
||||
}
|
||||
let blockSize = blocks[index]
|
||||
let maxPos = cells - (totalBlockSize + blocks.count - index - 1)
|
||||
let t = totalBlockSize - blockSize
|
||||
var c = cells - (blockSize + 1)
|
||||
for pos in 0...maxPos {
|
||||
fill(value: ".", offset: offset, count: maxPos + blockSize)
|
||||
fill(value: "#", offset: offset + pos, count: blockSize)
|
||||
solve(cells: c, index: index + 1, totalBlockSize: t,
|
||||
offset: offset + blockSize + pos + 1)
|
||||
c -= 1
|
||||
}
|
||||
}
|
||||
|
||||
func fill(value: Character, offset: Int, count: Int) {
|
||||
output.replaceSubrange(offset..<offset+count,
|
||||
with: repeatElement(value, count: count))
|
||||
}
|
||||
|
||||
var output: [Character] = Array(repeating: ".", count: cells)
|
||||
var count = 0
|
||||
solve(cells: cells, index: 0, totalBlockSize: totalBlockSize, offset: 0)
|
||||
}
|
||||
|
||||
nonoblock(cells: 5, blocks: [2, 1])
|
||||
print()
|
||||
|
||||
nonoblock(cells: 5, blocks: [])
|
||||
print()
|
||||
|
||||
nonoblock(cells: 10, blocks: [8])
|
||||
print()
|
||||
|
||||
nonoblock(cells: 15, blocks: [2, 3, 2, 3])
|
||||
print()
|
||||
|
||||
nonoblock(cells: 5, blocks: [2, 3])
|
||||
68
Task/Nonoblock/Tcl/nonoblock.tcl
Normal file
68
Task/Nonoblock/Tcl/nonoblock.tcl
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
package require Tcl 8.6
|
||||
package require generator
|
||||
|
||||
generator define nonoblocks {blocks cells} {
|
||||
set sum [tcl::mathop::+ {*}$blocks]
|
||||
if {$sum == 0 || [lindex $blocks 0] == 0} {
|
||||
generator yield {{0 0}}
|
||||
return
|
||||
} elseif {$sum + [llength $blocks] - 1 > $cells} {
|
||||
error "those blocks will not fit in those cells"
|
||||
}
|
||||
|
||||
set brest [lassign $blocks blen]
|
||||
for {set bpos 0} {$bpos <= $cells - $sum - [llength $brest]} {incr bpos} {
|
||||
if {![llength $brest]} {
|
||||
generator yield [list [list $bpos $blen]]
|
||||
return
|
||||
}
|
||||
set offset [expr {$bpos + $blen + 1}]
|
||||
generator foreach subpos [nonoblocks $brest [expr {$cells - $offset}]] {
|
||||
generator yield [linsert [lmap b $subpos {
|
||||
lset b 0 [expr {[lindex $b 0] + $offset}]
|
||||
}] 0 [list $bpos $blen]]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if {[info script] eq $::argv0} {
|
||||
proc pblock {cells {vec {}}} {
|
||||
set vector [lrepeat $cells "_"]
|
||||
set ch 64
|
||||
foreach b $vec {
|
||||
incr ch
|
||||
lassign $b bp bl
|
||||
for {set i $bp} {$i < $bp + $bl} {incr i} {
|
||||
lset vector $i [format %c $ch]
|
||||
}
|
||||
}
|
||||
return |[join $vector "|"]|
|
||||
}
|
||||
proc flist {items} {
|
||||
return [format "\[%s\]" [join $items ", "]]
|
||||
}
|
||||
foreach {blocks cells} {
|
||||
{2 1} 5
|
||||
{} 5
|
||||
{8} 10
|
||||
{2 3 2 3} 15
|
||||
{2 3} 5
|
||||
} {
|
||||
puts "\nConfiguration:"
|
||||
puts [format "%s # %d cells and %s blocks" \
|
||||
[pblock $cells] $cells [flist $blocks]]
|
||||
puts " Possibilities:"
|
||||
set i 0
|
||||
try {
|
||||
generator foreach vector [nonoblocks $blocks $cells] {
|
||||
puts " [pblock $cells $vector]"
|
||||
incr i
|
||||
}
|
||||
puts " A total of $i possible configurations"
|
||||
} on error msg {
|
||||
puts " --> ERROR: $msg"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
package provide nonoblock 1
|
||||
34
Task/Nonoblock/Wren/nonoblock.wren
Normal file
34
Task/Nonoblock/Wren/nonoblock.wren
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import "/math" for Nums
|
||||
|
||||
var genSequence // recursive
|
||||
genSequence = Fn.new { |ones, numZeros|
|
||||
if (ones.isEmpty) return ["0" * numZeros]
|
||||
var result = []
|
||||
for (x in 1...numZeros - ones.count + 2) {
|
||||
var skipOne = ones[1..-1]
|
||||
for (tail in genSequence.call(skipOne, numZeros - x)) {
|
||||
result.add("0" * x + ones[0] + tail)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
var printBlock = Fn.new { |data, len|
|
||||
var a = data.toList
|
||||
var sumChars = Nums.sum(a.map { |c| c.bytes[0] - 48 }.toList)
|
||||
System.print("\nblocks %(a), cells %(len)")
|
||||
if (len - sumChars <= 0) {
|
||||
System.print("No solution")
|
||||
return
|
||||
}
|
||||
var prep = a.map { |c| "1" * (c.bytes[0] - 48) }.toList
|
||||
for (r in genSequence.call(prep, len - sumChars + 1)) {
|
||||
System.print(r[1..-1])
|
||||
}
|
||||
}
|
||||
|
||||
printBlock.call("21", 5)
|
||||
printBlock.call("", 5)
|
||||
printBlock.call("8", 10)
|
||||
printBlock.call("2323", 15)
|
||||
printBlock.call("23", 5)
|
||||
33
Task/Nonoblock/Zkl/nonoblock-1.zkl
Normal file
33
Task/Nonoblock/Zkl/nonoblock-1.zkl
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
fcn nonoblocks(blocks,cells){
|
||||
if(not blocks or blocks[0]==0) vm.yield( T(T(0,0)) );
|
||||
else{
|
||||
if(not ( blocks.sum(0) + blocks.len() -1<=cells ))
|
||||
throw(Exception.AssertionError("Those blocks will not fit in those cells"));
|
||||
blength,brest:=blocks[0], blocks[1,*]; # Deal with the first block of length
|
||||
minspace4rest:=brest.reduce('+(1),0); # The other blocks need space
|
||||
# Slide the start position from left to max RH index allowing for other blocks.
|
||||
foreach bpos in (cells - minspace4rest - blength +1){
|
||||
if(not brest) # No other blocks to the right so just yield this one.
|
||||
vm.yield(T(T(bpos,blength)));
|
||||
else{
|
||||
# More blocks to the right so create a *sub-problem* of placing
|
||||
# the brest blocks in the cells one space to the right of the RHS of
|
||||
# this block.
|
||||
offset:=bpos + blength +1;
|
||||
# recursive call to nonoblocks yields multiple sub-positions
|
||||
foreach subpos in (Utils.Generator(nonoblocks,brest,cells - offset)){
|
||||
# Remove the offset from sub block positions
|
||||
rest:=subpos.pump(List,'wrap([(bp,bl)]){ T(offset + bp, bl) });
|
||||
# Yield this block plus sub blocks positions
|
||||
vm.yield(T( T(bpos,blength) ).extend(rest) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# Pretty print each run of blocks with a different letter for each block of filled cells
|
||||
fcn pblock(vec,cells){
|
||||
vector,ch:=cells.pump(List(),"_".copy), ["A".."Z"];
|
||||
vec.apply2('wrap([(a,b)]){ a.walker(b).pump(Void,vector.set.fp1(ch.next())) });
|
||||
String("|",vector.concat("|"),"|");
|
||||
}
|
||||
11
Task/Nonoblock/Zkl/nonoblock-2.zkl
Normal file
11
Task/Nonoblock/Zkl/nonoblock-2.zkl
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
foreach blocks,cells in (T( T(T(2,1),5), T(T,5), T(T(8),10), T(T(2,3,2,3),15),
|
||||
T(T(2,3),5) )){
|
||||
println("\nConfiguration:\n %s # %d cells and %s blocks"
|
||||
.fmt(pblock(T,cells),cells,blocks));
|
||||
println(" Possibilities:");
|
||||
Utils.Generator(nonoblocks,blocks,cells).reduce('wrap(n,vector){
|
||||
println(" ",pblock(vector,cells));
|
||||
n+1
|
||||
},0)
|
||||
: println(" A total of %d possible configurations.".fmt(_));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue