逆順になるあみだくじ
Posted feedbacks - Flatten
Nested Hidden
この問題はかなりおもしろかったです。
とりあえず無理矢理版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?php
$n=max(2,(int)$argv[1]);
$h=$n*2-2;
for($i=0;$i<$n;++$i)
echo " $i";
echo "\n";
for($i=0;$i<$h;++$i)
{ echo " |";
for($j=1;$j<$n;++$j)
{ $f=abs($i-($n-2))-($n-$j);
echo ($f<0 && ($f&1))?"_|":" |";
}
echo "\n";
}
for($i=$n;--$i>=0;)
echo " $i";
echo "\n";
?>
|
nが2桁以上でも動くように頑張りました。
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 | #include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int n; /* あみだの数 */
int keta; /* 数字の桁数 */
int *amida; /* あみだ */
int i, j, k; /* ループカウンタ */
int tmp; /* スワップ用 */
char *under; /* 移動線 */
/* nを決定する */
if (argc < 2) {
fprintf(stderr, "usage: %s n\n", argv[0]);
return 1;
}
n = atoi(argv[1]);
if (n < 2) {
n = 2;
}
keta = 1;
for (tmp = n+1; tmp >= 10; tmp /= 10) {
keta++;
}
/* あみだの初期化、一番上の数字の表示 */
amida = malloc(n * sizeof(*amida));
for (i = 0; i < n; i++) {
amida[i] = i;
}
under = malloc(keta * sizeof(*under));
for (i = 0; i < keta; i++) {
under[i] = '_';
}
for (i = 0; i < n; i++) {
printf("%d%*c", amida[i], keta, ' ');
}
printf("\n");
/* バブルソート */
for (i = 0; i < n-1; i++) {
for (j = 0; j < n-1; j++) {
if (amida[j] < amida[j+1]) {
/* 交換があるときに交換の表示をする */
tmp = amida[j];
amida[j] = amida[j+1];
amida[j+1] = tmp;
for (k = 0; k < n; k++) {
if (k == j) {
printf("|%s", under);
}
else {
printf("|%*c", keta, ' ');
}
}
printf("\n");
}
}
}
/* 最後の線と数字の表示 */
for (i = 0; i < n; i++) {
printf("|%*c", keta, ' ');
}
printf("\n");
for (i = 0; i < n; i++) {
printf("%-*d ", keta, amida[i]);
}
printf("\n");
free(amida);
free(under);
return 0;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def amida (n)
w = Math.log10(n - 1).to_i + 1
puts (0...n).to_a.map {|it| it.to_s.ljust(w + 1) } .join
((n - 1) * 2).times do
|lv|
r = (n - 2) - (lv - (n - 2)).abs
(0...n).to_a.map do
|t|
s = (t <= r and lv.odd? == t.odd?) ? '_' : ' '
print "|#{s * w}"
end
puts
end
puts (0...n).to_a.map {|it| it.to_s.ljust(w + 1) } .join
end
amida(ARGV.first.to_i)
|
amidaの最後(14行目)が反対だ!
1 | puts (0...n).to_a.reverse.map {|it| it.to_s.ljust(w + 1) } .join
|
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 | def dan(n, d)
ary = []
0.upto(d - 2) {|i|
s = "| " * n
s[-1] = ""
s[(d - i) * 2 - 3] = "_"
ary << s.dup
}
ary
end
n = ARGV[0].to_i
a = []
s = ""
1.upto(n) {|m|
s << "#{m} "
}
a << s
1.upto(n) {|m|
a << dan(n, m)
}
s = "| " * n
s[-1] = ""
a << s
s = ""
n.downto(1) {|m|
s << "#{m} "
}
a << s
a.each{|line|
puts line
}
|
odd? 追加したのを忘れていました。
すみません。すみません。
(一番はじめにいれてやれば動きます)
1 2 3 4 5 | class Fixnum
def odd?
self % 2 == 1
end
end
|
もうちょっとちゃんと考えた版
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 | <?php
$n=max(2,(int)$argv[1]);
$ladder=array();
for($i=0;$i<$n;++$i)
{ $ladder[$i]=$i;
printf("%2d",$i);
}
echo "\n";
do{ $c=0;
echo " |";
for($j=0;$j<$n-1;++$j)
{ if($ladder[$j]<$ladder[$j+1])
{ $t=$ladder[$j];
$ladder[$j]=$ladder[$j+1];
$ladder[$j+1]=$t;
echo "_|";
if(++$j<$n-1)
echo " |";
++$c;
}
else
echo " |";
}
echo "\n";
}while($c);
for($i=0;$i<$n;++$i)
printf("%2d",$ladder[$i]);
echo "\n";
?>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | function amida(n) {
var $ = [ '|', '_', '|', ' ', '|' ];
var result = numbers() + '\n';
for (var i = 0; i < n; i++) {
for (var j = 0, w = n * 2 - 1; j < w; j++) {
result += $[j % 4];
}
$.reverse();
result += '\n';
}
for (var i = 0; i < n; i++) {
result += '| ';
}
result += '\n';
return result + numbers().split('').reverse().join('') + '\n';
function numbers() {
for (var i = 0, line = ''; i < n; i++) line += i + ' ';
return line.substring(0, line.length - 1);
}
}
amida(5);
|
n > 11 だと表示が崩れるな…
…とかいってココサブさんの#740のパクリですすみません。 ひねりは加えてみた。
2桁の場合は無視してます。
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 | Number.prototype.amida = function()
{
var n = this;
var s = ["|","_","|"," "];
var tmp = "";
for (var i=0; i<n; i++)
tmp += (i+1).toString() + " ";
tmp += "\n";
for (var j=0; j<n; j++)
{
for (var i=0; i<n*2-1; i++)
{
tmp += s[(i+j*2)%4];
}
tmp += "\n";
}
for (var i=0; i<n*2-1; i++)
tmp += s[(i%2)+2];
tmp += "\n";
for (var i=n; i>0; i--)
tmp += (i).toString() + " ";
return tmp;
}
var n = 9;
alert(n.amida());
|
バブルソートの可視化の問題ですね。 これって、縦方向の量って圧縮できるんでしょうか。
ばれちゃいましたか。
わかる人はわかったようですね。
最初は「縦方向がもっとも圧縮されたものを表示してください」という
お題にしようかと思っていたのですけども、
あえて書かないことにしたのでした。
ネタバレついでに僕が試しに書いたコードのうち読みにくい方を投稿~。
1 | (lambda w:(lambda n,f:[w("%s "%i)for i in range(n)]and w("\n")or[f((i+x)%2 for x in range(n-1))for i in range(n)]and f([0]*(n-1))or[w("%s "%i)for i in reversed(range(n))]and w("\n"))(input("n=? >>>"),lambda b:w("|"+"|".join(" _"[c]for c in b)+"|"+"\n")))(__import__("sys").stdout.write)
|
なるほど、上下の数字の部分がずれるわけですね。 そこは今回のお題の肝ではないので、まぁいいのではないでしょうか。
おもしろい。というわけで勝手に拡張して、 「任意の列に対して、それをソートした結果になるあみだくじを生成」。 3項演算子使えばいいところに使ってないのは Zaurus で組んだから(ruby1.8.0 しか入れてなかったー) > amida 10 10 9 8 7 6 5 4 3 2 1 |__| |__| |__| |__| |__| (略) | |__| |__| |__| |__| | 1 2 3 4 5 6 7 8 9 10 > amidalist ["Tiger", "Zebra", "Cat", "Fox", "Dog"] Tiger Zebra Cat Fox Dog | |_____| |_____| |_____| |_____| | | |_____| |_____| | | |_____| | Cat Dog Fox Tiger Zebra
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 | def output(list, space)
puts list.inject(""){|buf,x|buf+="#{x} "[0,space+1]}
end
def amidalist(list)
space = list.inject(0){|m,x|n="#{x}".length;if m>n then m else n end}
output list, space
while true
flag = true, idx = 0, buf = "|"
while idx < list.length - 1
if list[idx] > list[idx+1]
list[idx], list[idx+1] = list[idx+1], list[idx]
buf += "_"*space + "|"
idx += 2
buf += " "*space + "|" if idx < list.length
flag = false
else
buf += " "*space + "|"
idx += 1
end
end
break if flag
puts buf
end
output list, space
end
def amida(n)
amidalist (1..n).to_a.reverse
end
|
縦方向にもっとも圧縮されたものに挑戦。 もっとも圧縮でn回になりそうですね。
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 | #include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int n; /* あみだの数 */
int keta; /* 数字の桁数 */
int i, j; /* ループカウンタ */
char *under; /* 移動線 */
/* nを決定する */
if (argc < 2) {
fprintf(stderr, "usage: %s n\n", argv[0]);
return 1;
}
n = atoi(argv[1]);
if (n < 2) {
n = 2;
}
keta = 1;
for (i = n+1; i >= 10; i /= 10) {
keta++;
}
/* 初期化、一番上の数字の表示 */
under = malloc((keta+1) * sizeof(*under));
memset(under, '_', keta);
under[keta] = '\0';
for (i = 0; i < n; i++) {
printf("%d%*c", i, keta, ' ');
}
printf("\n");
/* あみだ作成 */
for (i = 0; i < n; i++) {
if ((i % 2) == 0) {
j = 0;
}
else {
j = 1;
printf("|%*c", keta, ' ');
}
/* 実際に移動線がでるとこ */
for (; j+1 < n; j+=2) {
printf("|%s|%*c", under, keta, ' ');
}
if (j+1 <= n) {
printf("|%*c", keta, ' ');
}
printf("\n");
}
/* 最後の縦線と数字の表示 */
for (i = 0; i < n; i++) {
printf("|%*c", keta, ' ');
}
printf("\n");
for (i = 0; i < n; i++) {
printf("%-*d ", keta, n-i-1);
}
printf("\n");
free(under);
return 0;
}
|
rubyist率高いね ITER> (amida 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 | (require :iterate)
(in-package :iter)
(defun %bars (n)
"横棒の座標のリストを求める"
(labels ((limit (i j) (<= (+ i j) (* 2 (1- n)))))
(iter outer
(for i from 1 to (* 2 (1- n)))
(appending
(if (oddp i)
(iter (for j from 1 to i by 2)
(when (limit i j) (collect (cons i j))))
(iter (for j from 2 to i by 2)
(when (limit i j) (collect (cons i j)))))))))
(defun %draw (n bars)
"横棒の座標リストからアミダを描く"
(labels ((empty ()
(iter (for i from 1 to n) (format t "| "))
(terpri)))
(empty)
(iter (for i from 1 to (* 2 (1- n)))
(iter (for j from 1 to n)
(format t "|~a" (if (member (cons i j) bars :test #'equal)
"-" " ")))
(terpri))))
(defun amida (n)
(%draw n (%bars n)))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using System;
class Program
{
static void Main()
{
int n = 6;
for (int i = 0; i < n; ++i) Console.Write("{0} ", i);
Console.WriteLine();
for (int i = 1; i < 2 * n - 1; ++i)
{
int k = i < n ? i + 1 : 2 * n - 1 - i;
for (int j = 1; j < n; ++j)
Console.Write("|{0}", j <= k && (k - j) % 2 == 1 ? "_" : " ");
Console.WriteLine("|");
}
for (int i = n - 1; i >= 0; --i) Console.Write("{0} ", i);
Console.WriteLine();
}
}
|
M-x amida
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 | (require 'cl)
(defun %bars (n)
"横棒の座標のリストを求める"
(labels ((limit (i j) (<= (+ i j) (* 2 (1- n)))))
(loop for i from 1 to (* 2 (1- n)) appending
(if (oddp i)
(loop for j from 1 to i by 2
when (limit i j)
collect (cons i j))
(loop for j from 2 to i by 2
when (limit i j) collect (cons i j))))))
;; (%bars 5)
(defun %draw (n bars)
"横棒の座標リストからアミダを描く"
(with-output-to-temp-buffer "*amida*"
(labels ((empty ()
(loop for i from 1 to n do (princ "| "))
(terpri)))
(empty)
(loop for i from 1 to (* 2 (1- n)) do
(loop for j from 1 to n do
(princ "|")
(princ (if (member (cons i j) bars) "-" " ")))
(terpri)))))
(defun amida (n)
(interactive "sN: ")
(setq n (string-to-number n))
(%draw n (%bars n)))
|
Squeak Smalltalk で n が 10 以下で(^_^;)。あと「n はプログラムを書き換えずに指定できるように」が「n を引数に取る関数として and/or 起動時オプションとして指定できるように書け」という意味なら、そのようにはしていないのでごめんなさい。(GUI な Squeak Smalltalk 環境ではそうするメリットが少ない←関数 and/or そもそもできない←起動時オプション なので…)
1 2 3 4 5 6 7 8 9 10 11 12 13 | | n labels numOfVBarsPair m last |
n := 10.
World findATranscript: nil.
numOfVBarsPair := {m := (n alignedTo: 2) / 2. m - (n \\ 2)}.
Transcript cr; show: (labels := String streamContents: [:ss |
(1 to: n) do: [:i | ss print: i - 1] separatedBy: [ss space]]).
1 to: (last := numOfVBarsPair first * 2 + (n - 1 \\ 2)) do: [:row |
Transcript cr; show: '|'.
1 to: n - 1 do: [:i |
| vBarOrSp |
vBarOrSp := row < last ifTrue: [' _' atWrap: i + row] ifFalse: [$ ].
Transcript nextPut: vBarOrSp; nextPut: $|]].
Transcript cr; show: labels reversed
|
難しかったです。結果として「任意の列に対して、それをソートした結果になるあみだくじを生成」版になってると思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | let rec make_ladder = function
| [] -> print_newline (); []
| [x] -> print_endline "| "; [x]
| x::y::xs when x < y -> print_string "|_| "; (y::x::make_ladder xs)
| x::y::xs -> print_string "| "; (x::make_ladder (y::xs))
let rec amida l =
let rec complete = function
| [x] -> true
| x::y::xs -> x > y && complete (y::xs)
in
if (complete l) then make_ladder l
else (amida (make_ladder l))
;;
|
すみませんっ!
* 無加工(text)
* 整形済み(pre)
の意味が分かっていませんでした。orz
可能でしたら上のコメントの修正お願いします。m(__)m
んー、D言語にはネスト関数があるから書き易い~
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 | module doukaku;
private import std.stdio;
struct Bar {
int i;
int j;
}
Bar[] bars(int n) {
Bar[] bars;
int limit(int i, int j) { return (i+j) <= 2*(n-1); }
int i,j;
void append(int i, int j) {
if (limit(i, j)) {
Bar bar;
bar.i = i;
bar.j = j;
bars ~= bar;
}
}
for (i=1; i<=2*(n-1); i++) {
if (i%2 == 1) {
for (j=1; j<=i; j+=2) append(i, j);
} else {
for (j=2; j<=i; j+=2) append(i, j);
}
}
return bars;
}
int member(int i, int j, Bar[] bars) {
foreach (bar; bars) {
if (i==bar.i && j==bar.j) return 1;
}
return 0;
}
void draw(int n, Bar[] bars) {
int i,j;
void empty() {
for (int i=1; i<=n; i++) writef("| ");
writefln("");
}
empty();
for (i=1; i<=2*(n-1); i++) {
for (j=1; j<=n; j++) {
writef("|");
if (member(i, j, bars))
writef("-");
else
writef(" ");
}
writefln("");
}
}
void amida(int n) {
draw(n, bars(n));
}
void main() {
amida(10);
}
|
再帰つらい…orz
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 | (define (bars n)
(define (limit i j) (<= (+ i j) (* 2 (- n 1))))
(define (oddp n) (= (remainder n 2) 1))
(define (append0 i j result)
(if (limit i j)
(cons (cons i j) result)
result))
(define (rec i j result)
(cond ((<= i (* 2 (- n 1)))
(if (<= j i)
(rec i (+ j 2) (append0 i j result))
(rec (+ i 1) (if (oddp (+ i 1)) 1 2) result)))
(else
result)))
(rec 1 1 ()))
(define (draw n bars)
(define (empty i)
(cond ((<= i n)
(display "| ")
(empty (+ i 1)))
(else
(display "\n"))))
(define (rec i j)
(cond ((<= j n)
(cond ((<= i (* 2 (- n 1)))
(display "|")
(display (if (member (cons i j) bars) "-" " "))
(rec i |




にしお
#3376()
Rating0/0=0.00
たとえばnが3の場合は下のように出力してください。
nはプログラムを書き換えずに指定できるようにしてください。このお題はoceanさんの投稿を元に作成しました。ご投稿ありがとうございます。
[ reply ]