ビンゴの結果を整形表示
Posted feedbacks - Flatten
Nested Hiddenenumeratorで
1 2 3 4 5 6 7 8 9 10 11 12 13 | def bingo(num)
(1..num).to_a.sort_by{ rand }
end
require 'enumerator'
bingo(35).enum_slice(10).each_with_index{ |e,index|
num=index * 10 + 1
tmpl=(["%02s"] * e.size).join(' ')
puts tmpl % (num .. num + e.size).to_a
puts tmpl % e
puts ""
}
|
リストを選んだ意味があまりなくなってしまいましたが、前のお題にそのまま出力機能を加えました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import java.util.*;
public class Sample2 {
public static List<Integer> bingo(int num) {
Integer[] deck = new Integer[num];
for (int i = 0; i < num; i++) {
deck[i] = i + 1;
}
List<Integer> nums = (List<Integer>) Arrays.asList(deck);
Collections.shuffle(nums);
return nums;
}
public static void printBingo(int num) {
List<Integer> nums = bingo(num);
for (int j = 0; j < num; j += 10) {
for (int i = j; i < j + 10 && i < num; i++) {
System.out.printf("%3d", i + 1);
}
System.out.println();
for (int i = j; i < j + 10 && i < num; i++) {
System.out.printf("%3d", nums.get(i));
}
System.out.printf("%n%n");
}
}
public static void main(String[] args) {
printBingo(Integer.parseInt(args[0]));
}
}
|
showBingoがビンゴの整数リストを文字列に変換する 関数。第一引数は数字の最大桁数 shuffle は前回と同じだけど再掲
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | module Main (main) where
import Data.List
import System.Environment
import System.Random
import Text.Printf
shuffle :: [a] -> StdGen -> Int -> [a] -> [a]
shuffle acc _ 0 _ = acc
shuffle acc g n xs = case randomR (0,n-1) g of
(i,g') -> case splitAt i xs of
(ys,z:zs) -> shuffle (z:acc) g' (n-1) (ys++zs)
main :: IO ()
main = do { x:_ <- getArgs
; g0 <- getStdGen
; let n = read x
; putStr $ showBingo (length x)
$ shuffle [] g0 n [1..n]
}
showBingo :: Int -> [Int] -> String
showBingo w = unlines . map (showLines w) . map unzip . slice 10 . zip [1..]
slice :: Int -> [a] -> [[a]]
slice n = unfoldr phi
where phi [] = Nothing
phi xs = Just $ splitAt n xs
showLines :: Int -> ([Int],[Int]) -> String
showLines n (xs,ys) = unlines [ unwords $ map (pr n) xs
, unwords $ map (pr n) ys]
pr :: Int -> Int -> String
pr w = printf $ "%"++show w++"d"
{-
% ./bingo 30
1 2 3 4 5 6 7 8 9 10
19 26 2 6 11 17 23 8 7 5
11 12 13 14 15 16 17 18 19 20
18 13 16 12 22 24 4 21 1 25
21 22 23 24 25 26 27 28 29 30
3 29 10 27 15 9 28 14 20 30
% ./bingo 35
1 2 3 4 5 6 7 8 9 10
20 32 18 3 29 13 33 1 24 21
11 12 13 14 15 16 17 18 19 20
17 12 34 4 25 8 31 30 14 35
21 22 23 24 25 26 27 28 29 30
10 11 7 16 19 15 23 27 9 22
31 32 33 34 35
2 28 5 6 26
-}
|
bingo(100)でも動作するようにしたつもり。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import random
import itertools
division = 10
def bingo(count):
a = [i + 1 for i in xrange(count)]
random.shuffle(a)
width = len(str(count)) + 1
it = ((i + 1, n) for (i, n) in enumerate(a))
while 1:
b = list(itertools.islice(it, division))
if not b:
break
for i in xrange(2):
print "".join(str(c[i]).rjust(width) for c in b)
print
def main():
bingo(30)
bingo(35)
if __name__ == '__main__':
main()
|
showBingo に (length x) を渡したけど、 (length (show n))を渡す方がよいかもです。
表示方法のみの変更なので show() 関数だけ変更
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | BEGIN {
srand
}
{
n = $1
bingo(n,ar)
show(n,ar)
}
function show(n,ar, i,j,k,s1,s2)
{
s1 = s2 = ""
k = length(n)
for (i=1; i<=n; i++) {
s1 = s1 sprintf(" %"k"d", i+j)
s2 = s2 sprintf(" %"k"d", ar[i+j])
if (i % 10 == 0) {
print s1
print s2
print ""
s1 = s2 = ""
}
}
if (s1 !~ /^$/) { # n % 10 > 0
print s1
print s2
print ""
}
}
function rand_between_1_and_n(n, x)
{
x = 1 + int(rand * n)
return (x <= n)? x : rand_between_1_and_n(n)
}
function bingo(n,ar, i,x,y,t)
{
delete ar;
for (i=1; i<=n; i++) ar[i] = i
for (i=n*2; i>0; i--) {
x = rand_between_1_and_n(n)
y = rand_between_1_and_n(n)
if (x == y) continue
t = ar[x] ; ar[x] = ar[y] ; ar[y] = t
}
}
|
出力はこんな感じ % awk -f bingo2.awk 5 1 2 3 4 5 1 4 5 2 3 10 1 2 3 4 5 6 7 8 9 10 3 8 2 7 1 5 4 9 10 6 15 1 2 3 4 5 6 7 8 9 10 9 5 13 2 15 14 6 11 4 12 11 12 13 14 15 8 10 3 1 7 19 1 2 3 4 5 6 7 8 9 10 5 11 10 1 12 15 3 7 17 9 11 12 13 14 15 16 17 18 19 19 18 8 6 2 4 16 14 13 20 1 2 3 4 5 6 7 8 9 10 1 4 10 9 14 20 3 6 18 19 11 12 13 14 15 16 17 18 19 20 17 15 8 16 13 5 12 2 7 11 21 1 2 3 4 5 6 7 8 9 10 5 16 11 4 10 15 18 2 1 9 11 12 13 14 15 16 17 18 19 20 19 7 6 8 13 3 12 14 21 17 21 20 30 1 2 3 4 5 6 7 8 9 10 21 26 7 24 23 5 17 10 16 9 11 12 13 14 15 16 17 18 19 20 11 20 12 30 1 14 18 4 15 6 21 22 23 24 25 26 27 28 29 30 22 8 3 25 28 19 27 29 13 2 100 1 2 3 4 5 6 7 8 9 10 55 98 44 13 99 81 53 61 56 87 11 12 13 14 15 16 17 18 19 20 82 24 52 92 66 51 18 70 19 58 21 22 23 24 25 26 27 28 29 30 41 47 39 43 94 8 80 59 42 79 31 32 33 34 35 36 37 38 39 40 27 73 36 12 62 37 83 9 54 96 41 42 43 44 45 46 47 48 49 50 69 84 45 17 26 100 50 67 6 1 51 52 53 54 55 56 57 58 59 60 15 65 4 33 16 5 78 23 74 75 61 62 63 64 65 66 67 68 69 70 63 38 40 28 91 89 72 34 77 35 71 72 73 74 75 76 77 78 79 80 11 2 21 30 49 3 71 57 25 31 81 82 83 84 85 86 87 88 89 90 14 10 93 60 85 90 46 88 48 32 91 92 93 94 95 96 97 98 99 100 22 95 7 68 29 20 64 97 86 76
bingo関数自体は#2255からいただきました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from random import shuffle
def bingo(n):
l = range(1, n+1)
shuffle(l)
return l
def bingo_print(l):
fmt = '%%%sd' % len(str(len(l)))
a = range(1, len(l)+1)
for i in range(0, len(l), 10):
print ' '.join([fmt % j for j in a[i:i+10]])
print ' '.join([fmt % j for j in l[i:i+10]]) + '\n'
bingo_print(bingo(30))
bingo_print(bingo(35))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #light
let rec bingo n = shuffle [1..n]
and shuffle ls =
let rnd = new System.Random()
List.sort (fun x y-> rnd.Next(-1,2)) ls
let printLine ln n =
let rec len (m:int) = ( m.ToString() ).Length
and mk (m:int) = (String.make ((len n) - (len m)) ' ') ^ m.ToString()
and (|SplitAt|) m xs = List.partition (fun (x,i) -> i <= m) xs
and mkLns c = function
| [] -> []
| SplitAt c (head,tail) -> (List.unzip head)::mkLns (c+ln) tail
and concatMap f xs = String.concat " " <| List.map f xs
and bs = mkLns ln (List.zip (bingo n) [1..n])
[for (xs,ids) in bs -> (concatMap mk xs) ^ "\n" ^ (concatMap mk ids)]
|> String.concat "\n"
|> printf "%s\n"
let bingoPr = fun n -> printLine 10 n
|
修正。 |> String.concat "\n" じゃなくて |> String.concat "\n\n" としないとお題のようにならないですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import scala.util.Sorting.stableSort
def bingo(n:int) = {
type PList = List[Pair[int,int]]
val lst = stableSort[int,double](1 to n,x=>Math.random).zipWithIndex.toList
val w = lst.size.toString.size+1
def format(n:int) = String.format("%"+w+"d",Array(n.asInstanceOf[AnyRef]))
def printline(x:PList) = {
println(x.map(y=>format(y._2+1)).mkString(""))
println(x.map(y=>format(y._1)).mkString("")+"\n")
}
def show(l:PList):unit = l.splitAt(10) match {
case (l,Nil) => printline(l)
case (l,ls) => printline(l);show(ls)
}
show(lst)
}
bingo(30)
bingo(35)
|
bingo関数自体が結果を出力していたので出力部分を変更。 リストに何番目かの値もInsertして出力してます。全然短くできず。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | Public Sub bingo(ByVal n As Integer)
Dim list As New List(Of Integer)
For i As Integer = 1 To n
list.Add(i)
Next
Dim r As New Random
For i As Integer = 1 To n * 2
Dim index As Integer = r.Next(0, n)
list.Add(list(index))
list.RemoveAt(index)
Next
For i As Integer = 0 To n - 1
list.Insert((i \ 10) * 20 + i Mod 10, i + 1)
Next
For i As Integer = 1 To list.Count - 1
Console.Write(list(i - 1).ToString.PadLeft(n.ToString.Length) & Space(-CInt(CBool(i Mod 10 <> 0))))
If i Mod 10 = 0 OrElse i = list.Count - n Mod 10 Then
Console.WriteLine(New String(ControlChars.Lf, -CInt(CBool(i Mod 20 = 0))))
End If
Next
Console.WriteLine(list(list.Count - 1))
End Sub
|
ちょっとゴチャゴチャしてる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import Random (randomRIO)
import Data.List ((\\),elemIndex)
import Data.Maybe (fromJust)
import Control.Monad (zipWithM_)
bingo :: Int -> IO [Int]
bingo n = b [1..n] n []
where b [] n ret = return ret
b xs (n+1) ret = do
r <- randomRIO (0,n)
let m = xs !! r in b (xs \\ [m]) n (ret ++ [m])
showBingo :: Int -> IO ()
showBingo n = bingo n >>= \xs -> zipWithM_ printBingo (f idxs) (f (t xs))
where idxs = [1..n]
f = map concat . map u . s
s xs = if xs == [] then [] else let (h,t) = splitAt 10 xs in h:s t
t xs = map ((1+) . fromJust . (\x -> x `elemIndex` idxs)) xs
u xs = let len = length (show n) in map (surpress (len + 1) . show) xs
surpress n xs = reverse $ take n $ reverse xs ++ cycle " "
printBingo x y = putStrLn x >> putStrLn y >> putStrLn ""
|
Squeak Smalltalk で。
1 2 3 4 5 6 7 8 9 10 11 12 | | n size bingo streams |
n := 35.
size := n printString size + 1.
bingo := (1 to: n) asArray shuffled readStream.
streams := {String new writeStream. String new writeStream}.
World findATranscript: nil.
1 to: n do: [:idx |
{idx. bingo next} with: streams do: [:int :strm |
strm nextPutAll: (int printPaddedWith: $ to: size)].
((idx isDivisibleBy: 10) or: [idx = n]) ifTrue: [
Transcript cr.
streams do: [:strm | Transcript cr; show: strm contents. strm reset]]]
|
シーケンスのshuffleはライブラリに追加しようかなあ。 今回のお題はshow-bingo関数で実装してます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | (use srfi-1)
(use srfi-27)
(use srfi-42)
(use gauche.sequence)
(use util.list)
(define (shuffle! seq)
(do-ec (: n (- (size-of seq) 1) 0 -1)
(let1 p (random-integer (+ n 1))
(unless (= p n)
(let1 tmp (ref seq n)
(set! (ref seq n) (ref seq p))
(set! (ref seq p) tmp)))))
seq)
(define (bingo n) (shuffle! (iota n 1)))
(define (show-bingo lis)
(do-ec (: row (slices (zip (iota (length lis) 1) lis) 10))
(begin
(do-ec (: p row) (format #t "~3d" (car p))) (newline)
(do-ec (: p row) (format #t "~3d" (cadr p))) (newline) (newline))))
|
ブラウザとCScriptに対応。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Array.prototype.$huffle = function(){
for(var $, r, i = this.length; i;)
$ = this[r = Math.random() * i-- | 0], this[r] = this[i], this[i] = $;
return this;
};
function bingo(n, w){
if(!w) w = 10;
for(var a = [], i = 1; i <= n;) a[a.length] = i++;
var b = a.concat().$huffle(), r = [], l = (' '+ n).length;
while(a.length) r[r.length] = a.splice(0, w).join(' ') +'\n'+ b.splice(0, w).join(' ');
r = r.join('\n\n').replace(/ *\d+/g, function($){ while($.length < l) $ = ' '+ $; return $ });
if(typeof WSH != 'undefined') WSH.stdOut.write(r);
else document.write('<pre>'+ r +'</pre>');
}
|
出力データをまとめてprintしてみた。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from random import shuffle
def bingo(n):
l = range(1, n+1)
shuffle(l)
return l
def bingo_print(l):
fmt = '%%%sd' % len(str(len(l)))
a = [fmt % i for i in range(1, len(l)+1)]
b = [fmt % i for i in l]
print '\n'.join(['%s\n%s\n' % (' '.join(a[i:i+10]), ' '.join(b[i:i+10])) for i in range(0, len(l), 10)])
bingo_print(bingo(30))
bingo_print(bingo(35))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | using System;
using System.Text;
class Program
{
static void Main()
{
PrintBingo(35);
}
static void PrintBingo(int n)
{
Random r = new Random();
int[] a = new int[n];
for (int i = 0; i < n; ++i) a[i] = i + 1;
for (int i = n; i > 1; --i)
{
int k = r.Next(i);
int tmp = a[i - 1];
a[i - 1] = a[k];
a[k] = tmp;
}
for (int i = 0; i < n; i++)
{
if (i % 10 == 0)
{
if (i > 0) Console.WriteLine("\n");
for (int j = i; j < Math.Min(n, i + 10); j++)
Console.Write("{0,3}", j + 1);
Console.WriteLine();
}
Console.Write("{0,3}", a[i]);
}
Console.WriteLine();
}
}
|
bingo関数自体#2289から少し変更しました。
(print-bingo (bingo 25))
(print-bingo (bingo 25))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | (defun bingo (n)
(let ((*random-state* (make-random-state t)))
(loop repeat n
for rand = (loop
(let ((rand (1+ (random n))))
(if (not (member rand lst))
(return rand))))
collect rand into lst
finally (return lst))))
(defun print-bingo (lst)
(let ((index 0)
(format-string (concatenate
'string
"~{~"
(princ-to-string (1+ (length (princ-to-string (length lst)))))
"d~}~%" )))
(loop for elements on lst by #'(lambda (x) (nthcdr 10 x))
do (loop repeat 10
for e in elements
collect (incf index) into column-name
collect e into column-value
finally (format t format-string column-name)
(format t format-string column-value)
(terpri)))))
|
ブックマークレット版: javascript:(function(n,w,a,b,r,l,i,$){for(a=[],l=('_'+n).length,i=0;i<n;a.push(++i));for(b=a.concat();n;$=b[i=Math.random()*n--|0],b[i]=b[n],b[n]=$);for(r=[];a.length;r.push(a.splice(0,w).join(' ')+'\n'+b.splice(0,w).join(' ')));return'<pre>'+r.join('\n\n').replace(/ *\d+/g,function($){while($.length<l)$=' '+$;return $})+'</pre>'})(35,10)
出力用の関数を追加。 ちょっとドロくさいかな?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | sub bingo($;)
{
my $x = shift ;
my @num = (1 .. $x);
my $r;
for( my $n = $x; $n>0; $n --)
{
$r = rand; $r *= 1000;
push(@num, splice(@num, $r % $n, 1) );
}
return @num;
}
sub printTable(@)
{
my @T = @_;
my $N, $K;
printf("[%d] => \n", $#T+1);
for( $N=0; $N<=$#T; $N = $K + 1)
{
# 番号
for( $K=$N; $K<$#T; $K ++ )
{
last if ($K-$N) >= 9;
printf("%2d ", $K+1);
}
printf("%2d\n", $K+1);
# 乱数
for( $K=$N; $K<$#T; $K ++ )
{
last if ($K-$N) >= 9;
printf("%2d ", $T[$K]);
}
printf("%2d\n", $T[$K]);
printf("\n");
}
}
my @table;
srand;
@table = bingo(30); ::printTable(@table);
@table = bingo(35); ::printTable(@table);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <?php
function bingo($n){
$a = range(1, $n);
shuffle($a);
return $a;
}
function show($a){
$max = strlen(max($a));
$html = array("<pre>\n");
for($i=0; $i<count($a); $i+=10){
for($j=$i, $number=$counter=array(); $j<$i+10; $j++){
if($j>=count($a)) break;
$counter[] = sprintf("% {$max}d", $j+1);
$number[] = sprintf("% {$max}d", $a[$j]);
}
$html[] = sprintf("%s\n%s\n\n", join(" ", $counter), join(" ", $number));
}
$html[] = "</pre>";
return join("", $html);
}
echo show(bingo(30));
echo show(bingo(35));
?>
|
10個ずつspliceすれば綺麗に書けると思ったんだけど、なんかごちゃごちゃしてしまった。
1 2 3 4 5 6 7 8 9 10 11 12 13 | use List::Util qw/shuffle/;
sub bingo {p(shuffle(1..$_[0]));}
sub p {
my $i = 1;
while(my @sublist = splice(@_,0,10)){
for my $seq ($i..$i+scalar(@sublist)-1){printf "%3d", $seq;};
print "\n";
for my $num (@sublist){printf "%3d", $num;};
print "\n\n";
$i = $i + scalar(@sublist);
}
}
|
あら、しまった。言語をperlにし忘れた。修正できん。
混ざり具合は良くないですが(-_-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include <stdio.h>
#include <stdlib.h>
static int cmp(const void *p1, const void *p2)
{
return (rand() % 2)?1:-1;
}
int *bingo(int num)
{
int i, n;
int *nums;
if(num <= 0) return NULL;
nums = (int*)malloc(sizeof(int) * num);
for(i=0; i<num; i++){
nums[i] = i + 1;
}
qsort(nums, num, sizeof(int), (int (*)(const void*, const void*))cmp);
return nums;
}
void bingo_print(int *nums, int n)
{
int i, j;
for(i=0; i<n; i=j){
for(j=i; j < n && (i == j || j % 10); j++)
printf("%2d ", j + 1);
printf("\n");
for(j=i; j < n && (i == j || j % 10); j++)
printf("%2d ", nums[j]);
printf("\n\n");
}
}
int main(int argc, char *argv[])
{
int n;
int *nums;
if(argc < 2) return EXIT_FAILURE;
n = atoi(argv[1]);
srand(time(NULL));
nums = bingo(n);
bingo_print(nums, n);
free(nums);
return EXIT_SUCCESS;
}
|
僕が出題前に書いたコードはこんな感じですが、 確かに#2324みたいにrangeのstepを使った方がいいですね。 スライシングで添え字の範囲が超えてもエラーにならないので僕のコードの18行目以降みたいな 「1行に満たない残りがあれば表示」というコードがいらなくなるわけですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | def bingo(n):
from random import shuffle
result = range(1, n + 1)
shuffle(result)
w = len(str(n))
format = " %%%dd" % w
nbuf = []
rbuf = []
for i in range(n):
nbuf.append(format % (i + 1))
rbuf.append(format % result[i])
if i % 10 == 9:
print "".join(nbuf)
print "".join(rbuf)
print
nbuf = []
rbuf = []
if nbuf:
print "".join(nbuf)
print "".join(rbuf)
|
修正しました。
すいません、ありがとうございます。
bcc32とg++で確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cstdlib>
#ifdef _WIN32
# include <windows.h>
# define seed() ::GetCurrentTime()
#else
# include <ctime>
# define seed() std::time(NULL)
#endif
struct RandomGenerator
{
RandomGenerator()
{
std::srand(static_cast<unsigned>(seed()));
}
int operator()(int n) const
{
const int i = static_cast<int>(static_cast<double>(std::rand()) * n / RAND_MAX);
return std::max(0, std::min(i, n - 1));
}
};
std::vector<size_t> create_bingo(size_t n)
{
std::vector<size_t> v;
for (size_t i = 0; i < n; ++i)
{
v.push_back(i);
}
static RandomGenerator gen;
std::random_shuffle(v.begin(), v.end(), gen);
return v;
}
void output(size_t value, size_t width)
{
std::cout.width(width);
std::cout << value;
}
size_t calculate_width(size_t value)
{
size_t width = 1;
for (; value >= 10; value /= 10)
{
++width;
}
return width;
}
void bingo(size_t n)
{
const std::vector<size_t> v = create_bingo(n);
const size_t width = calculate_width(n) + 1;
const size_t unit = 10;
for (size_t beg = 0; beg < v.size(); beg += unit)
{
const size_t end = std::min(beg + unit, v.size());
for (size_t i = beg; i < end; ++i)
{
output(i + 1, width);
}
std::cout << std::endl;
for (size_t i = beg; i < end; ++i)
{
output(v[i], width);
}
std::cout << std::endl << std::endl;
}
}
int main()
{
bingo(30);
bingo(35);
}
|
マニピュレータを使ってみた。
see: setw
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | --- main.orig Fri Aug 24 13:50:54 2007
+++ main.cpp Fri Aug 24 13:53:20 2007
@@ -1,4 +1,5 @@
#include <iostream>
+#include <iomanip>
#include <vector>
#include <algorithm>
#include <iterator>
@@ -43,13 +44,6 @@
return v;
}
-void output(size_t value, size_t width)
-{
- std::cout.width(width);
-
- std::cout << value;
-}
-
size_t calculate_width(size_t value)
{
size_t width = 1;
@@ -76,14 +70,14 @@
for (size_t i = beg; i < end; ++i)
{
- output(i + 1, width);
+ std::cout << std::setw(width) << (i + 1);
}
std::cout << std::endl;
for (size_t i = beg; i < end; ++i)
{
- output(v[i], width);
+ std::cout << std::setw(width) << v[i];
}
std::cout << std::endl << std::endl;
|
PS C:\> format-bingo(bingo(5)) 1 2 3 4 5 4 2 1 0 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function bingo([int] $n)
{
$r = new-object system.random
$a = 0..($n-1)
0..($n-1) | %{ $i = $r.next($n-1); $a[$_],$a[$i] = $a[$i],$a[$_] }
$a
}
function format-bingo($ary)
{
$keta = ([string]$ary.length).length + 1
for ($i = 0; $i -lt $ary.length; $i+=10) {
$len = $ary[($i)..($i+9)].length + $i
[string]::join("", (@(($i+1)..$len) | %{"{0,$keta}" -f $_}))
[string]::join("", ($ary[($i)..($len-1)] | %{"{0,$keta}" -f $_}))
""
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | shuffle([], []).
shuffle(X, [R|Y]) :- length(X, XL), N is random(XL),
nth0(N, X, R), select(R, X, X1), shuffle(X1, Y).
write_row(L, W) :- write_row(L, W, W).
write_row( [], _, _) :- nl.
write_row([X|L], W, Tab) :- format('~t~d~*|', [X, Tab]),
Tab1 is Tab + W + 1, write_row(L, W, Tab1).
write_bingo(W, X, S) :-
length(X, N), N > 10,
nth0(10, X, XE), append(XL, [XE|XR], X),
nth0(10, S, SE), append(SL, [SE|SR], S),
write_row(XL, W), write_row(SL, W), nl,
write_bingo(W, [XE|XR], [SE|SR]).
write_bingo(W, X, S) :- write_row(X, W), write_row(S, W).
bingo(N) :- findall(X, between(1, N, X), L), shuffle(L, S),
atom_number(A, N), atom_length(A, T), write_bingo(T, L, S).
|
perlで書いてみた
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | sub bingo()
{
my @array = ( 1 .. shift );
my @out = ();
while ( my $x = splice( @array, int(rand(scalar @array)) , 1 ) )
{
push @out , $x ;
}
return [ @out ];
}
sub out()
{
my @array = @{ $_[0] };
my $i=1;
while ( my @x = splice( @array, 0 , 10 ) )
{
my $n = scalar @x ;
my $comp = (int($i/$n)+1) * $n;
while ( $i <= $comp )
{
printf "%3d", $i++;
}
print "\n";
while(my $a = shift @x )
{
printf "%3d" , $a ;
}
print "\n\n";
}
}
&out( &bingo(35) );
|
1行に10個とか,ラベルを付けてとか,空行を挟むとか言うことがなければ単に bingo <- sample でよいのだが。。。 > bingo(35) 1 2 3 4 5 6 7 8 9 10 28 30 18 14 8 15 9 29 4 19 11 12 13 14 15 16 17 18 19 20 16 2 21 3 22 24 27 26 31 13 21 22 23 24 25 26 27 28 29 30 34 11 7 20 23 25 33 5 1 6 31 32 33 34 35 17 35 10 32 12
1 2 3 4 5 6 7 8 9 10 | bingo <- function(n) {
m <- sample(n)
names(m) <- 1:n
for (i in 0:((n-1)%/%10)) {
is <- i*10+1
ie <- min(is+9, n)
print(m[is:ie])
cat("\n")
}
}
|
表示桁指定は * でできますが、表示桁の求め方を 2 種類用意しました。
1. libm をリンクして、log10 を使う方法
2. stderr を捨てて fprintf を使う方法
1. libm をリンクして、log10 を使う方法
2. stderr を捨てて fprintf を使う方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include <stdio.h>
#include <time.h>
#include <stdlib.h>
//#include <math.h>
void bingo( int n ){
int tmp;
int i,j;
//int k = (int)log10( n )+1;
int k = fprintf(stderr, "%d",n);
int *deck = (int*)malloc(sizeof(int)*n);
for( i = 0; i < n; i++ )
deck[i] = i+1;
for( i = 0; i < n; i++ ){
j = rand() % (n-i);
tmp = deck[j];
deck[j] = deck[ n-i-1 ];
deck[ n-i-1 ] = tmp;
}
for( i = 0; i < n; i+=10){
for( j = i; j < i+10 && j < n; j++ )
printf("%*d ", k, j+1 );
printf("\n");
for( j = i; j < i+10 && j < n; j++ )
printf("%*d ", k, deck[j] );
printf("\n");
printf("\n");
}
free(deck);
}
int main ( void ){
srand(time(NULL));
bingo(9);
printf("\n");
bingo(23);
printf("\n");
return 0;
}
|
長くなってしまいましたが・・・
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ビンゴ(30)
●ビンゴ(n)
bとは文字列
cとは文字列
nbとは整数=バイト数(n)
//ビンゴを生成
ビンゴ生成(n)を反復
b=b&文字列右寄せ(対象,nb)&" "
b=bを(nb+1)*10で行揃え
//回数も生成
iで1からnまで繰り返す
c=c&文字列右寄せ(i,nb)&" "
c=cを(nb+1)*10で行揃え
//表示
(切り上げ(n/10))回
c[回数-1]を表示
b[回数-1]を表示
空を表示
●ビンゴ生成(n)
rとは配列
(n)回
rに回数を配列追加
rを配列シャッフル
rで戻る
|
無理やり短く・・・
1 2 3 4 5 | ビンゴ(30)
●ビンゴ(n)
xとは整数=(文字数(n)+2);cとは配列;bとは配列;ビンゴ生成(n)で反復;b=b&文字列右寄(対象,x);c=c&文字列右寄(回数,x);もし(回数=n)ならば;b=行揃(b,(x*10));行揃(c,(x*10))で反復;表示(対象&改行&b[回数-1]&改行)
●ビンゴ生成(n)
rとは配列;(n)回;配列追加(r,回数);もし(回数=n)ならば;戻(配列シャッフル(r))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | call srand tickcount;
call bingo 35;
endmacro;
bingo:
##i = 0;
while( ##i < ##1 ) {
##dest[##i] = ##i + 1;
##i = ##i + 1;
}
##i = 0;
while( ##i < ##1 ) {
call rand;
##r = ##return % ( ##1 - ##i ) + ##i;
##tmp = ##dest[##r];
##dest[##r] = ##dest[##i];
##dest[##i] = ##tmp;
##i = ##i + 1;
}
##keta = strlen( str( ##1 ) );
##i = 0;
while( ##i < ##1 ) {
##next = ##i + 10;
if ( ##next > ##1 ) {
##next = ##1;
}
##ii = ##i;
while( ##ii < ##next ) {
if ( ##ii > ##i ) {
insert " ";
}
call KetaSoroe ##ii+1, ##keta;
insert $$return;
##ii = ##ii + 1;
}
insert "\n";
##ii = ##i;
while( ##ii < ##next ) {
if ( ##ii > ##i ) {
insert " ";
}
call KetaSoroe ##dest[##ii], ##keta;
insert $$return;
##ii = ##ii + 1;
}
insert "\n\n";
##i = ##next;
}
return;
KetaSoroe:
##i = ##2 - strlen( str( ##1 ) );
$$result = "";
if ( ##i >= 0 ) {
while( ##i > 0 ) {
$$result = $$result + " ";
##i = ##i - 1;
}
}
$$result = $$result + str( ##1 );
return $$result;
rand:
#rand_x = #rand_x * 214013 + 2531011;
if ( #rand_x < 0 ) {
return ( ( #rand_x + 1 ) / 65536 - 1 ) & 32767;
}
return #rand_x / 65536 & 32767;
srand:
#rand_x = ##1;
return;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import std.random;
import std.stdio;
import std.string;
void show_bingo(int n, int[] xs) {
int i;
int j = cast(int)(toString(n).length);
string s1;
string s2;
foreach (x; xs) {
s1 ~= format("%*d ", j, i);
s2 ~= format("%*d ", j, x);
if (0 == (++i % 10)) {
writefln("%s\n%s\n", chop(s1), chop(s2));
s1 = s2 = "";
}
}
if ("" != s1) {
writefln("%s\n%s\n", chop(s1), chop(s2));
}
}
void bingo(int n)
{
int[] xs;
for (int i = 1; i <= n; ++i) {
xs ~= i;
}
for (int i = 0; i < n; ++i) {
uint r = rand() % n;
int tmp = xs[r];
xs[r] = xs[i];
xs[i] = tmp;
}
show_bingo(n, xs);
}
/*
void main() {
bingo(30);
bingo(35);
}
*/
|
formatでの整数指定がBなのに気がつかず、
ちょっと悩みました。
実数指定はC言語と同じくfなのに…。
1> c(show_bingo).
{ok,show_bingo}
2> show_bingo:bingo(30).
1 2 3 4 5 6 7 8 9 10
23 19 12 14 2 13 29 7 1 26
11 12 13 14 15 16 17 18 19 20
4 5 24 20 16 8 22 30 3 17
21 22 23 24 25 26 27 28 29 30
6 9 18 25 15 21 28 11 27 10
ok
3> show_bingo:bingo(35).
1 2 3 4 5 6 7 8 9 10
5 2 21 29 10 33 4 7 20 6
11 12 13 14 15 16 17 18 19 20
34 30 3 16 24 22 23 12 18 14
21 22 23 24 25 26 27 28 29 30
17 28 9 15 26 13 11 8 27 1
31 32 33 34 35
25 35 32 19 31
ok
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | -module(show_bingo).
-export([bingo/1]).
show_line([X | []], Size) -> io:format("~" ++ Size ++ "B~n", [X]);
show_line([X | XS], Size) ->
io:format("~" ++ Size ++ "B ", [X]),
show_line(XS, Size).
column_size(Num) ->
Max = length(lists:last(io_lib:format("~B", [Num]))),
lists:last(io_lib:format("~B", [Max])).
bingo_sub(Num) -> bingo_sub(lists:seq(1, Num), Num * Num).
bingo_sub(List, 0) -> List;
bingo_sub(List, Num) ->
R = lists:nth(random:uniform(length(List)), List),
bingo_sub([R] ++ [X || X <- List, X =/= R], Num - 1).
bingo(Num) -> bingo(bingo_sub(Num), lists:seq(1, Num), column_size(Num)).
bingo([], _, _) -> true;
bingo(Rnd, Seq, Size) ->
if
length(Rnd) > 10 ->
show_line(lists:sublist(Seq, 10), Size),
show_line(lists:sublist(Rnd, 10), Size),
io:nl(),
bingo(lists:nthtail(10, Rnd), lists:nthtail(10, Seq), Size);
true ->
show_line(Seq, Size),
show_line(Rnd, Size)
end.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | (* bingo定義はhttp://ja.doukaku.org/comment/5033/ *)
let (%%) x y = (x/y*y=x) ;;
let print_bingo arr =
let times = Array.length arr in
let iter last x y f =
(for i = x to (min last y) do (f i) done) in
let pr = Printf.printf "%3d" in
let nl = print_newline in
let print_turn n x =
if (x%%n) then (
nl(); nl();
iter times (x+1) (x+n) (pr);
nl();
);
in
Array.iteri (fun i x -> print_turn 10 i; pr x) arr;;
print_bingo (bingo 35);;
|
特にありません.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | N = 22
def put_bingo(n, col)
d = n.to_s.size + 1
index = Array.new(n){|i| i+1}
bingo = Array.new(n){|i| index.delete_at(rand(n-i).modulo(n-i))}.
map{|x| sprintf("% #{d}d", x)} #bingoの結果を生成
(n.div(col) + 1).times{|i|
size = bingo.size
index = Array.new(size >= col ? col : size){|j| sprintf("% #{d}d", i*10+j+1)}.join
result = bingo.slice!(0..(size >= col ? 9 : -1)).join
puts "#{index}\n#{result}\n\n" if result.size > 0
}
end
put_bingo(N, 10) #引数はbingoの大きさと出力時の列数の2つ
|
#5208 同様、dmd 2.009 ではコンパイルできません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import std.stdio;
import std.random;
import std.string;
void bingo(uint n){
uint[] a;
a.length = n;
foreach(i, ref e; a){
e = i + 1;
}
randomShuffle(a, Random(unpredictableSeed()));
uint max = 10;
string[] indexBuf, randBuf;
int numWidth = toString(n).length;
foreach(i, e; a){
indexBuf ~= format("%*d", numWidth, i + 1);
randBuf ~= format("%*d", numWidth, e);
if((i + 1) % max == 0 || i == a.length - 1){
writeln(indexBuf.join(" "));
writeln(randBuf.join(" "));
if(i != a.length - 1){
writeln();
}
indexBuf.length = randBuf.length = 0;
}
}
}
void main(){
bingo(30);
writeln("----");
bingo(35);
}
|
「重複無し乱数」で投稿したものを手直ししました。そろそろバッチでできることの限界
が見えてきたような気がします。
e.g.
C:\>bingo 30
1 2 3 4 5 6 7 8 9 10
6 14 2 13 4 28 20 9 12 16
11 12 13 14 15 16 17 18 19 20
26 15 1 30 21 25 27 22 19 29
21 22 23 24 25 26 27 28 29 30
3 23 10 24 5 18 11 17 7 8
C:\>bingo 35
1 2 3 4 5 6 7 8 9 10
10 24 34 13 2 25 17 14 8 30
11 12 13 14 15 16 17 18 19 20
29 12 23 20 18 31 9 6 27 11
21 22 23 24 25 26 27 28 29 30
33 5 35 1 15 21 3 32 26 22
31 32 33 34 35
28 7 19 16 4
遅延環境変数展開を利用しているので、Windows NTでは動作しません。Windows XPで動作
を確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | :: bingo.bat
@echo off
setlocal enabledelayedexpansion
set C=10
set i=0
set j=0
set k=0
set l=0
set m=0
set s=
set t=
set v=0
echo %1|findstr /r "[^0-9]" >NUL 2>&1
if %ERRORLEVEL% equ 0 (echo %~n0 [NUMBER] & goto :EOF)
if %1 equ 0 goto :EOF
:: 擬似配列を生成
for /l %%i in (1,1,%1) do set v_%%i=%%i
:: 値をシャッフル
call :length %1 l
echo set j=%%RANDOM:~-%l%%%>_.bat
set i=1
:shuffle
:: 8進数として解釈されないよう 0を加算
call _.bat & set /a j+=0
set /a j=%j%%%%1+1
set v=!v_%i%!
set v_%i%=!v_%j%!
set v_%j%=%v%
set /a i+=1
if %i% lss %1 goto shuffle
del _.bat
:: 結果を整形表示
set /a i=%1/%C%
set /a m=%1%%%C%
if %m% gtr 0 set /a i+=1
set j=1
set k=%C%
if %1 lss %C% set k=%1
for /l %%i in (1,1,%i%) do (
:: 上段
set s=
for /l %%j in (!j!,1,!k!) do (
set t=%%j
if %%j lss %1 call :lpad !t! %l% t
set s=!s!!t!
if %%j lss !k! set s=!s!
)
echo !s!
:: 下段
set s=
for /l %%j in (!j!,1,!k!) do (
set t=
call :lpad !v_%%j! %l% t
set s=!s!!t!
if %%j lss !k! set s=!s!
)
echo !s!
if %%i lss %i% echo.
set /a j+=%C%
set /a k+=%C%
if !k! gtr %1 set k=%1
)
endlocal
goto :EOF
:lpad
setlocal enabledelayedexpansion
set l=0
set t=
call :length %1 l
set /a l=%2-%l%
for /l %%i in (1,1,%l%) do set t=!t!
endlocal & set %3=%t%%1
goto :EOF
:length
setlocal
set i=0
set t=%1
set t=%t:"=%
:loop
set t=%t:~1%
set /a i+=1
if not "%t%" == "" goto loop
endlocal & set %2=%i%
goto :EOF
|
bingo2 7 1 2 3 4 5 6 7 2 1 4 3 7 5 6 bingo2 17 1 2 3 4 5 6 7 8 9 10 14 7 3 9 15 17 10 16 1 4 11 12 13 14 15 16 17 5 8 2 12 11 13 6
1 | bingo2=:3 :'_10(>:#":y.)&":&|:\>:(i.,.?~)y.'
|
率直に言ってgroupByを使うべきケースでしょうこれは。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def bingo(n) {
(1..n).toList().sort{ Math.random() }
}
def bingoprint(n) {
def bingo = bingo(n)
(1..n).groupBy{(it-1).intdiv(10)}.each{k,v->
v.each{printf "%3d",it};println()
v.each{printf "%3d",bingo[it-1]};println("\n")
}
}
bingoprint(30)
bingoprint(35)
|






raynstard
#3403()
Rating1/1=1.00
「重複無し乱数」で作ったbingo関数の結果を下のように「何番目の乱数か」とセットにして10個ずつ折り返して表示するコードを書いてください。
[ reply ]