与えられた文字列でピラミッド
Posted feedbacks - Flatten
Nested Hidden末尾の空白の数がサンプル出力と違いますが、題意になかったのでスルーしました。 chainは引数のイテレータを順番に実行するイテレータを返す関数です。
1 2 3 4 5 6 7 8 9 10 11 12 | pyramid: fun(str) {
space: [" "].cycle;
arr: str.split("").to_a;
n: arr.length;
n.times.map(|i| i + 1){
chain(space.take(n - it ),
arr.slice(n - it, n).zip(space).map(|a,b| a~b)).join("").p;
}
}
pyramid("hoge");
pyramid("abracadabra");
|
文字を1文字づつ配列にするメソッドがあるのかどうかわからないので作りました。 Sequence split は 引数をあたえないと空白でわけるようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 | Sequence splitEvery := method(
l := list()
self foreach(v,
l append(v asCharacter)
)
return l
)
pyramid := method(str,
t := str size * 2 - 1
for(i, 1, str size,
str slice(str size - i, str size) splitEvery join(" ") alignCenter(t, " ") println
)
)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | String.prototype.repeat = function(n) {
for(var i=0, str=""; i < n; i++) {
str += this;
}
return str;
}
String.prototype.alignCenter = function(n, str) {
var r = (n - this.length) / 2;
return str.repeat(r) + this + str.repeat(r);
}
var pyramid = function(str) {
var t = str.length * 2 - 1
var res = ""
for(var i=1, len=str.length; i<=len; i++) {
res += str.slice(str.length - i, str.length).split("").join(" ").alignCenter(t, " ") + "\n"
}
return res;
}
|
String.alignCenter を修正
1 2 3 4 | String.prototype.alignCenter = function(n, str) {
var r = (n - this.length) / 2
return str.repeat(Math.floor(r)) + this + str.repeat(Math.ceil(r));
}
|
瞬殺
1 | str="abracadabra"; (str.length-1).downto(0) {|i| print(" "*i, str[i..-1].split(//).join(" "),"\n") }
|
キモいコードでごめんなさい。
1 2 3 4 5 6 7 | sub pyramid {
my $i = my @py = split //, $_[0];
print ' ' x $i . "@py[$i..$#py]\n" while $i--;
}
pyramid('hoge');
pyramid('abracadabra');
|
1 2 3 4 5 6 7 8 9 | function pyramid(str)
len = string.len(str)
for i=len, 1, -1 do
io.stdout:write(string.rep(" ",i-1))
for j=i, len, 1 do io.stdout:write(string.sub(str,j,j), " ") end
io.stdout:write("\n")
end
end
pyramid("abracadabra")
|
Scheme用SLIMEがあればいいのに…
1 2 3 4 5 6 7 8 | (use srfi-1)
(define (pyramid str)
(map
(lambda (i)
(format #t "~a~a~%" (make-string i)
(string-join (map string (string->list str i (string-length str))) " ")))
(iota (- (string-length str) 0) (- (string-length str) 1) -1)))
(pyramid "abracadabra")
|
loop以外で部分文字列の取り方がわからんorz
1 2 3 4 5 6 7 8 9 10 | (defun pyramid (str)
(loop for i from (1- (length str)) downto 0 do
(format t "~a~a~%"
(make-string i :initial-element #\Space)
(apply #'concatenate 'string
(loop for c across str
for j from 0
when (<= i j)
collect (format nil "~c~a" c " "))))))
(pyramid "abracadabra")
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h>
void pyramid(char *str) {
int i,j,len;
len = strlen(str);
for (i=len-1; i>=0; i--) {
for(j=0; j<i; j++) printf(" ");
for(j=i; j<len; j++) printf("%c%c", str[j], ' ');
printf("\n");
}
}
int main() {
pyramid("abracadabra");
return 0;
}
|
C書いた直後にDを書くと、文字列の扱いを混同してしまった
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private import std.stdio;
void pyramid(char[] str) {
int i,j;
for (i=str.length-1; i>=0; i--) {
for(j=0; j<i; j++) writef(" ");
for(j=i; j<str.length; j++) writef("%s%s", str[j], " ");
writef("\n");
}
}
int main() {
pyramid("abracadabra");
return 0;
}
|
1 2 3 4 5 6 7 8 | (require 'cl)
(defun pyramid (str)
(interactive "sPyramid string: ")
(with-output-to-temp-buffer "*Pyramid*"
(loop for i from (1- (length str)) downto 0 do
(princ (make-string i ? ))
(princ (mapconcat 'identity (split-string (substring str i) "") " "))
(terpri))))
|
Cと変わらねえww
1 2 3 4 5 6 7 8 9 10 11 12 | function pyramid () {
str=$1
len=`expr length $str`
for ((i=$len; i>=1; i--)); do
for ((j=0; j<$i; j++)); do echo -n ' '; done
for ((j=$i; j<=$len; j++)); do
echo -n `expr substr $str $j 1`' '
done
echo
done
}
pyramid "abracadabra"
|
文字列のインデックスアクセスも算術演算も明示的ループも無しで。
1 2 3 4 5 6 | (use util.list)
(define (pyramid s)
(let r ((s (string->list s)) (p '()))
(unless (null? s)
(r (cdr s) (cons #\ p))
(apply print (append p (intersperse #\ s))))))
|
明示的算術演算なし版。自分では再帰も書かない版です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import Data.List
binapp o f g x = f x `o` g x
pyramid = binapp (zipWith (++)) (map (map (const ' ')) . tail . tails)
(map (intersperse ' ') . tail . inits)
printPyramid = putStr . unlines . pyramid
{-
*Main> printPyramid "abracadabra"
a
a b
a b r
a b r a
a b r a c
a b r a c a
a b r a c a d
a b r a c a d a
a b r a c a d a b
a b r a c a d a b r
a b r a c a d a b r a
-}
|
% awk -f pyramid.awk hogehogehoge
e
g e
o g e
h o g e
e h o g e
g e h o g e
o g e h o g e
h o g e h o g e
e h o g e h o g e
g e h o g e h o g e
o g e h o g e h o g e
h o g e h o g e h o g e
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | BEGIN {
if (length(ARGV[1]) > 0) printf pyramid(ARGV[1])
}
function pyramid(str, N,moji,i,j)
{
N = split(str,moji,"")
s = ""
a = moji[1]; for (i=2; i<=N; i++) a = a " " moji[i] ## a = moji.join(' ')
for (i=N; i>=1; i--) {
s = a "\n" s
sub(/[a-z]/,"",a) ## 先頭から1文字ずつ消していく
}
return s
}
|
1 2 3 4 5 6 | def pyramid(s):
for i in range(len(s)):
print ' '.join(s[~i:]).center(len(s)*2-1)
pyramid('hoge')
pyramid('abracadabra')
|
名前付きletは明示的loopじゃないと?:)
だめじゃんこれ、題意を読み違えてる。
題意を読み違えてたので再投稿
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import Data.List
binapp o f g x = f x `o` g x
pyramid = binapp (zipWith (++)) (map (map (const ' ')) . tail)
(map (intersperse ' ') . tail . reverse)
. tails
printPyramid = putStr . unlines . pyramid
{-
*Main> printPyramid "abracadabra"
a
r a
b r a
a b r a
d a b r a
a d a b r a
c a d a b r a
a c a d a b r a
r a c a d a b r a
b r a c a d a b r a
a b r a c a d a b r a
-}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php
function pyramid($data) {
$stclm = strlen($data);
for ( $i = strlen($data) - 1; $i > -1; $i-- ) {
$stclm--;
echo str_pad("",$stclm," ",STR_PAD_LEFT);
for ( $j = $i; $j < strlen($data); $j++ ) {
echo substr($data,$j,1)." ";
}
echo "\n";
}
}
pyramid("hoge");
pyramid("abracadabra");
?>
|
1 2 3 4 5 6 | def pyramid(s:String) = {
val (len, cs) = (s.size-1, s.toList)
len.until(-1,-1).map(cs.splitAt).foreach{p =>
println((p._1.map(x=>""):::p._2).mkString(" "))
}
}
|
>部分文字列の取り方
subseq です?
subseq です?
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 | #include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
void pyramid(const std::string& s)
{
for (std::string::const_iterator it = s.end(); it != s.begin(); --it)
{
const size_t n = std::distance(s.begin(), it - 1);
std::fill_n(std::ostream_iterator<char>(std::cout), n, ' ');
std::copy(it - 1, s.end() - 1, std::ostream_iterator<char>(std::cout, " "));
std::cout << *(s.end() - 1);
std::fill_n(std::ostream_iterator<char>(std::cout), n, ' ');
std::cout << std::endl;
}
}
int main()
{
pyramid("hoge");
pyramid("abracadabra");
}
|
まとめてprint
1 2 3 4 5 | def pyramid(s):
print '\n'.join([' '*i + ' '.join(s[i:]) for i in range(len(s)-1, -1, -1)]),
pyramid('hoge')
pyramid('abracadabra')
|
phpって変な関数いっぱいあるな。
1 2 3 4 5 6 7 8 9 10 | function pyramid($str) {
$splt;
for ($i = 0; $i < strlen($str); $i++) {
$s = str_split(substr($str,$i,strlen($str)));
$splt[] = str_repeat(" ", $i) .join(" ",$s);
}
krsort($splt);
return join("\n",$splt);
}
echo pyramid("abracadabra");
|
名前付けてるだけだも〜ん。
それにいわゆる「ループとしての使いかた」はしてないし。
上記は英語のみ。 日本語混ざると死にます。
Never mind ! :)
シンプルに。
javascript:(function(p,r,m,d){for(p=p.split(''),r=[],m=p.length,d=0;m--;p[d++]='')r[m]=p.join(' ');return'<pre>'+r.join('\n')+'</pre>'})('abracadabra')
javascript:(function(p,r,m,d){for(p=p.split(''),r=[],m=p.length,d=0;m--;p[d++]='')r[m]=p.join(' ');return'<pre>'+r.join('\n')+'</pre>'})('abracadabra')
1 2 3 4 5 | function pyramid(s){
s = s.split('');
for(var r = [], i = s.length, j = 0; i--; s[j++] = "") r[i] = s.join(' ');
return r.join('\n');
}
|
Squeak Smalltalk で。
1 2 3 4 5 6 | | input |
input := 'abracadabra'.
World findATranscript: nil.
1 to: input size do: [:len |
Transcript cr; show: (String new: input size - len withAll: $ ).
(input last: len) do: [:each | Transcript show: each] separatedBy: [Transcript space]]
|
Rubyに対する対抗意識w
1 | s="abracadabra";n=len(s);print"\n".join(" ".join(s[~i:]).center(n*2-1)for i in range(n))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Pyramid {
public static void main(String[] args) {
String data = args.length > 0 ? args[0] : "abracatabra";
char[] spaceChars = new char[data.length()-1];
java.util.Arrays.fill(spaceChars, ' ');
String space = new String(spaceChars);
for(int i=0;i<data.length();i++) {
System.out.println(space.substring(i)
+ data.substring(data.length()-1-i).replaceAll("(.)(?=.)","$1 "));
}
}
}
|
お、phpの投稿が増えてる。 ということで私なりに…。
1 2 3 4 5 6 7 8 9 10 | <?php
function pyramid($str)
{
$len=strlen($str);
$str=implode(" ",str_split($str));
for($i=1;$i<=$len;++$i)
echo str_repeat(" ", $len-$i),substr($str,-($i*2-1)),"\n";
}
echo pyramid("abracadabra");
?>
|
ぐはっ。9行目のechoは余計…。コピーしたのもろバレ。 ということでついでに別解。 空の文字列の並んだ配列をスペース挟んで繋ぐと 勝手にセンタリングされるという…。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php
function pyramid($str)
{
$i=strlen($str);
$a=array_fill( 0, $i, "");
while(--$i>=0)
{ $a[$i]=$str[$i];
echo implode(" ",$a),"\n";
}
}
pyramid("abracadabra");
?>
|
1 2 3 4 5 6 7 8 9 | Sub pyramid(ByVal block As String)
For i As Integer = 0 To block.Length - 1
Dim line As String = Space(block.Length - i - 1)
For j As Integer = 0 To i
line &= " " & block.Substring(block.Length - i - 1 + j, 1)
Next
Console.WriteLine(line.Substring(1))
Next
End Sub
|
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 | #include <stdio.h>
#include <string.h>
void put_s(int n)
{
int i;
for (i = 0; i < n; i++) putchar(' ');
}
void put_c(const char *s)
{
putchar(*s);
while (*++s) {
putchar(' ');
putchar(*s);
}
}
void pyramid(const char *s)
{
int n;
n = strlen(s);
while (--n >= 0) {
put_s(n);
put_c(s + n);
put_s(n);
putchar('\n');
}
}
int main()
{
pyramid("hoge");
pyramid("abracadabra");
return 0;
}
|
REPLと二人三脚で作りました。
1 2 3 4 5 6 7 8 9 | (defun pyramid (str)
(let ((base (coerce (cdr (reduce (lambda (r x) `(,@r #\Space ,x))
(coerce str 'list)
:initial-value '())) 'string)))
(do ((idx 2 (+ idx 2))
(len (length base))
(result base (concatenate 'string spacer (subseq base idx) "~%" result))
(spacer " " (concatenate 'string " " spacer)))
((> idx len) (format t result)))))
|
ベタに書いてみました
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
$p_mess="hoge";
echo "<textarea cols=100 rows=20>";
echo pyramid($p_mess);
echo "</textarea>";
$p_mess="abracadabra";
echo "<textarea cols=100 rows=20>";
echo pyramid($p_mess);
echo "</textarea>";
function pyramid($p_mess)
{
$p_len=strlen($p_mess);
for($i=1;$i<=$p_len;$i++) //縦方向ループ
{
$w="";
for($j=$p_len-$i;$j<=$p_len;$j++) //横方向ループ、x行目=後ろからx文字分をループ
{
$w.=substr($p_mess,$j,1)." "; //切り出し+空白文字をwに入れ込む
}
$w=str_pad($w,$p_len*2+1," ",STR_PAD_BOTH); //左右に[ ]を埋める
$ret.=rtrim($w)."\n"; //右側の空白ははずす
}
return $ret;
}
?>
|
あえてリストベースで format 頼りの処理. コードの長さが気になるが恥さらしで.
1 2 3 4 5 6 7 8 9 10 11 12 13 | (defun pyramid (string)
(let ((chars (coerce string 'list)) (floors nil))
(labels
((make-floors (list n-space)
(unless (null list)
(push (format nil "~{~A~}~{~A~^ ~}~%"
(make-list n-space :initial-element #\Space) list)
floors)
(make-floors (cdr list) (1+ n-space)))))
(make-floors chars 0))
(mapcan #'(lambda (string)
(format t "~A" string))
floors)))
|
1 2 3 4 5 6 7 8 | <?php
function pyramid($str){
for($i=$j=$n=strlen($str); $i>0; $i--, $n=$j*2-$i)
printf("% {$n}s\n", trim(join(" ", preg_split("//", substr($str, $i-1, $j)))));
}
pyramid("abracadabra");
?>
|
Control.Arrowを中途半端につかってみました。
*Main> pyramid "abracadabra"
a
r a
b r a
a b r a
d a b r a
a d a b r a
c a d a b r a
a c a d a b r a
r a c a d a b r a
b r a c a d a b r a
a b r a c a d a b r a
1 2 3 4 5 | import Control.Arrow
import Data.List (tails,intersperse)
pyramid = id &&& length >>> first (tails >>> reverse >>> tail >>> map (id &&& length)) >>> uncurry f
where f xs len = mapM_ (\(x,y) -> putStrLn $ (++) (replicate (len - y) ' ') $ intersperse ' ' x) xs
|
maplist できれいに書けそうに思ったのですがスペースの調整が美しくなく、 結局 loop のほうがすっきりした形になりました。
1 2 3 4 | (defun pyramid (string)
(loop for x on (coerce string 'list) for i from 0 with tmp
collect (format nil "~VT,0~{~A~^ ~}" i x) into tmp
finally (mapc #'write-line (nreverse tmp))))
|
ごめんなさい間違ったものを送信してしまいました。 こっちが正しいコードです。
1 2 3 4 | (defun pyramid (string)
(loop for x on (coerce string 'list) for i from 0
collect (format nil "~V,0T~{~A~^ ~}" i x) into tmp
finally (mapc #'write-line (nreverse tmp))))
|
素直にループで。 今見ると#689の冗長さが何とも・・・。
1 2 3 | pyramid <- function(s, n=nchar(s), s2=unlist(strsplit(s, ''))){
for(i in n:1) cat(c(character(i-1), s2[i:n]), fill=TRUE)
}
|
PHP、ありそうでなかった再帰版。 超シンプル!
1 2 3 4 5 | function pyramid( $str, $_=''){
echo strlen($str)? pyramid( substr($str,1), "$_ ")."\n$_"
: null, join( ' ', preg_split('//',$str));
}
pyramid('abracadabra');
|
初めて投稿します。
Traversableを使って手続き型言語っぽく書いてみました。
*Main> pyramid "abracadabra"
a
r a
b r a
a b r a
d a b r a
a d a b r a
c a d a b r a
a c a d a b r a
r a c a d a b r a
b r a c a d a b r a
a b r a c a d a b r a
1 2 3 4 5 6 7 8 9 | import Data.List
import Data.Traversable
pyramid str = do
for (reverse $ p str) putStrLn
return ()
where
p (x:xs) = (intersperse ' ' (x:xs)) : map (' ':) (p xs)
p [] = []
|
ちょっと修正。 trim取ったり、substrの引数取ったり。
1 2 3 4 5 6 7 8 | <?php
function pyramid($str){
for($i=$n=strlen($str); $i>=0; $i--, $n=strlen($str)*2-$i+1)
printf("% {$n}s\n", join(" ", preg_split("//", substr($str, $i))));
}
pyramid("abracadabra");
?>
|
なるほど。似たアルゴリズムでControl.Applicableを使わないで書いてみた。 zipWith (flip const) xs ≡ take (length xs) です。(個人的ポリシーによりlengthはなるだけ使わない)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import Data.List
pyramid :: String -> [String]
pyramid xs
= map bar -- 片リストから行リストへ
$ reverse -- リストを反転,上片から下片へ
$ zipWith (flip const) xs -- xs の長さ分切り取る
$ iterate foo ("",xs) -- 下片から上片へのリスト
foo :: (String, String) -> (String, String)
foo (indent,str) = (' ':indent, tail str) -- 下片から1つ上片を求める
bar :: (String,String) -> String
bar (indent,str) = indent ++ intersperse ' ' str -- 片から行へ変換
{-
*Main> putStr $ unlines $ pyramid "hoge"
e
g e
o g e
h o g e
-}
|
さらに starling と binapp' を用いて pyramid をポイントフリースタイルに書きなおしたもの
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import Data.List
starling f g x = f x (g x)
binapp' o f g x y = f x `o` g y
pyramid' = map (uncurry bar') . reverse . starling (zipWith (flip const)) (iterate (uncurry foo') . ((,) ""))
foo' = binapp' (,) (' ':) tail
bar' = binapp' (++) id (intersperse ' ')
{-
*Main> putStr $ unlines $ pyramid' "hage"
e
g e
a g e
h a g e
-}
|
そうか、ということは unfoldr でも簡単に書けるんだ。 なるほど。。。勉強になるなぁ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import Data.List
pyramid :: String -> [String]
pyramid = reverse . unfoldr phi . (,) ""
where
phi (_ ,"") = Nothing
phi (xs,yys@(_:ys)) = Just (xs ++ intersperse ' ' yys,(' ':xs,ys))
{-
*Main> putStr $ unlines $ pyramid "hoge"
e
g e
o g e
h o g e
-}
|
デフォルト引数を使って単独の関数で再帰実装。 最下段の取り扱いが納得いかない。 全部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 25 26 27 28 29 30 31 32 33 34 35 36 | """
>>> pyramid("hoge")
e
g e
o g e
h o g e
>>> pyramid("abracadabra")
a
r a
b r a
a b r a
d a b r a
a d a b r a
c a d a b r a
a c a d a b r a
r a c a d a b r a
b r a c a d a b r a
a b r a c a d a b r a
"""
def pyramid(s, padding=None):
assert(len(s) > 0)
if padding is None:
padding = ' '
if len(s) == 1:
return s[0]
else:
p = pyramid(s[1:], padding + ' ')
print padding + p
if padding == ' ':
print s[0] + ' ' + p
else:
return s[0] + ' ' + p
import doctest
doctest.testmod()
|
あまり長くない文字列なら再帰でも行けます。
(Emacsは再帰の深さが変数max-lisp-eval-depthで制限されるので事実上使えない)
(pyramid "abracadabra")
a
r a
b r a
a b r a
d a b r a
a d a b r a
c a d a b r a
a c a d a b r a
r a c a d a b r a
b r a c a d a b r a
a b r a c a d a b r a
1 2 3 4 | (defun pyramid (s &optional p)
(unless (string= s "")
(pyramid (substring s 1) (cons ? p))
(insert (concat p) (mapconcat #'string s " ") "\n")))
|
1 2 3 4 5 6 | def strPyramid(s="abracadabra"):
s = " ".join(s)
length = len(s)
for i in range(length)[::-2]:
print s[i:].center(length,' ')
|
みなさんの投稿を参考にしつつ初投稿。
1 2 3 4 5 6 7 8 9 10 | let pyramid str =
let rec letters = function
| "" -> []
| s -> (String.sub s 0 1) :: (letters (String.sub s 1 (String.length s - 1)))
in
fst (List.fold_right (fun s t -> let x = s ^ snd t in (x :: (fst t), " " ^ x))
(letters str) ([], ""))
|> List.mapi (fun i s -> (String.make i ' ') ^ s) |> List.rev |> String.concat "\n";;
let _ = pyramid "abracadabra" |> printf "%s\n";;
|
\nをデリミタにしています。(\nh o g e) 1.1番目の項目を手前にコピー 2.ピラミッド一段上の形に合わせる 3.合わせたものが空白で埋まっていなければループ 最後に先頭の無駄な改行消してドン。
1 2 3 4 5 6 7 8 9 10 11 12 | #!/bin/sed -f
s/ //g
s/./ &/g
s/^ /\n/
:loop
s/^\n[^\n]*/&&/
s/^\(\n *\)[^ ] /\1 /
s/\n/ \n/2
/^\n *\n/!b loop
s/^\n *\n//
|
PS C:\> pyramid
a
r a
b r a
a b r a
d a b r a
a d a b r a
c a d a b r a
a c a d a b r a
r a c a d a b r a
b r a c a d a b r a
a b r a c a d a b r a
PS C:\> pyramid("hoge")
e
g e
o g e
h o g e
1 2 3 4 5 6 7 | function pyramid($s = "abracadabra") {
for ($i = 1; $i -le $s.length; $i++) {
$p = $s[-$i..-1]
$len = $s.length - $p.length
" " * $len + $p
}
}
|
#include <stdio.h>
#include <stdlib.h>
void pyramid(char* p)
{
int i, j, n = strlen(p);
char* buff = (char*)_alloca(n * n * 2);
memset(buff, ' ', n * n * 2);
for (i = 0; i < n; i++)
{
for (j = n * 2 * i + n - i - 1; j < n * n * 2; j += n * 2 + 1)
{
*(buff + j) = *(p + n - i - 1);
}
printf("%.*s\n", n * 2, buff + i * n * 2);
}
}
int main(int argc, char* argv[])
{
pyramid(argv[1]);
}
投稿し直し。2重ループ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <stdio.h>
#include <stdlib.h>
void pyramid(char* p)
{
int i, j, n = strlen(p);
char* buff = (char*)_alloca(n * n * 2);
memset(buff, ' ', n * n * 2);
for (i = 0; i < n; i++)
{
for (j = n * 2 * i + n - i - 1; j < n * n * 2; j += n * 2 + 1)
{
*(buff + j) = *(p + n - i - 1);
}
printf("%.*s\n", n * 2, buff + i * n * 2);
}
}
int main(int argc, char* argv[])
{
pyramid(argv[1]);
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using System;
using System.Text.RegularExpressions;
class Program {
static void pyramid(string s) {
int len = s.Length;
s = Regex.Replace(s, "(.)(?=.)", @"$1 ");
for (int n = len - 1; n >= 0; n--)
Console.WriteLine(s.Substring(n * 2).PadLeft(len * 2 - n).PadRight(len * 2));
}
static void Main(string[] args) {
pyramid("hoge");
pyramid("abracadabra");
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <iostream>
#include <string>
void pyramid(const std::string& src)
{
const int strLength = src.size();
const int lineLength = strLength * 2 - 1;
std::string line(strLength, ' ');
for(int i = strLength - 1; i >= 0; --i)
{
line[i] = src[i];
std::cout << line.substr(0, lineLength) << std::endl;
line = ' ' + line;
}
}
|
最初に思いついたもの。酷い。
1 2 3 | def pyramid str
str.chomp.reverse.gsub(/./){([" "*$'.size]*2)*(($`+$&).reverse.scan(/./)*" ")+$/}
end
|
ごり押し。 もっと分かり易くてうまいやり方があるはず。
see: Array#join と Array#last を調べた
1 2 3 4 5 6 7 8 9 | def pyramid(str)
n = str.length
1.upto(n) do |i|
result_str = str.split('').last(i).join
spaces = " " * (n - i)
puts result_str.split('').join(' ').insert(0, spaces)
end
end
pyramid("piyohoge")
|
ごり押しに変わりは無い。 表示させる文字列をあらかじめ String#reverse と String#split で反転・分解しておいた。
1 2 3 4 5 6 7 8 9 10 | def pyramid(str)
n = str.length
reversed_str_ary = str.reverse.split('')
n.times do |i|
result_str = reversed_str_ary[0..i].join
spaces = " " * (n - i)
puts result_str.split('').join(' ').insert(0, spaces)
end
end
pyramid("piyohoge")
|
これじゃダメだった。
このままだと、文字列が反転したまま表示されてしまう。
pyramid などの、引数の個数が0の場合を考えてなかったので、 pyramid(str = '') として、デフォルトで空文字列を与えた。
1 2 3 4 5 6 7 8 | def pyramid(str = '')
n = str.length
1.upto(n) do |i|
result_str = str.split('').last(i).join
spaces = " " * (n - i)
puts result_str.split('').join(' ').insert(0, spaces)
end
end
|
見た目がいかにも再帰っぽいと 再帰で書きたくなります。
1 2 3 4 5 6 7 8 9 10 11 | def pyramid(str, space = "")
if str == ""
""
else
pyramid(str[1, str.size-1], space+" ") +
space+str.split(//).join(" ")+"\n"
end
end
print pyramid("hoge")
print pyramid("abracadabra")
|
formatでセンタリング, 32=スペースで
1 2 3 4 5 6 7 8 | pyramid_sub([], _, []).
pyramid_sub([C|S], W, [32, C|S1]) :- pyramid_sub(S, W, S1),
format('~t~s~t~*|~n', [[C|S1], W]).
pyramid(S) :- length(S, N), W is (N * 2) - 1, pyramid_sub(S, W, _).
:- pyramid("hoge").
:- pyramid("abracadabra").
|
なんとかできた感じ、作った後にスライス使えばよかったなぁと後悔。
1 2 3 4 5 6 7 8 9 | def pyramid(s):
row=s[-1]
print ' '*(len(s)-1)+row
for i in range(2,len(s)+1):
row=s[-i]+' '+row
print ' '*(len(s)-i)+row
if __name__=='__main__':
pyramid('abracadabra')
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | call pyramid "hoge";
call pyramid "abracadabra";
endmacro;
pyramid:
##len = strlen( $$1 );
##i = ##len - 1;
while( ##i >= 0 ) {
##j = ##i;
while( ##j > 0 ) {
insert " ";
##j = ##j - 1;
}
##j = ##i;
while( ##j < ##len ) {
insert midstr( $$1, ##j, 1 );
insert " ";
##j = ##j + 1;
}
insert "\n";
##i = ##i - 1;
}
return;
|
1 2 3 4 5 6 7 8 9 | 「abracadabra」のピラミッドを表示
●ピラミッド(sの)
tとは配列
ケタ数=(2*バイト数(s)-1)
(バイト数(s))回
tに(文字列センタリング(文字列注入(RIGHT(s,回数)," "),ケタ数))を配列追加
tで戻る
●文字列注入(sにlを)
sを文字列分解してlで配列結合で戻る
|
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 | #include <stdio.h>
#include <string.h>
void print_pyramid(const char* s)
{
int i, j;
int n = strlen(s);
for (i=0; i<n; i++) {
for (j=n-i-2; j>=0; j--) putchar(' ');
for (j=n-i-1; j<n-1; j++) {
putchar(s[j]);
putchar(' ');
}
putchar(s[j]);
puts("");
}
}
int main(int argc, char** argv)
{
print_pyramid("hoge");
print_pyramid("abracadabra");
return 0;
}
|
なるほど。~iか。みんなの読んでると勉強なります。
1 2 3 4 5 6 | def pyramid(s):
for i in range(len(s)-1, -1, -1):
print " "*i + " ".join(s[i:])
pyramid("hoge")
pyramid("abracadabra")
|
pyramid2 'abracadabra'
a
r a
b r a
a b r a
d a b r a
a d a b r a
c a d a b r a
a c a d a b r a
r a c a d a b r a
b r a c a d a b r a
a b r a c a d a b r a
1 | pyramid2=.3 :'(,&a:<\.(<:#y)#'' ''),&;/"0([,'' '',])/&.>|.<\.y'
|
適当。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | fun pyramid s =
let
fun loop s' NONE = []
| loop s' (SOME c) =
let
val ns = subst (str c) "" s'
in
loop ns (CharVector.find Char.isGraph ns) @ [s']
end
val ss = (String.concatWith " " o global_slice ".") s
in
(app println o loop ss o SOME o sub) (ss, 0)
end
val _ = pyramid "hoge"
val _ = pyramid "abracadabra"
|
段階的に目的の文字列へ近づけ、最後に出力します。
1> c(string_pyramid).
{ok,string_pyramid}
2> string_pyramid:string_pyramid("hoge").
e
g e
o g e
h o g e
ok
3> string_pyramid:string_pyramid("abracadabra").
a
r a
b r a
a b r a
d a b r a
a d a b r a
c a d a b r a
a c a d a b r a
r a c a d a b r a
b r a c a d a b r a
a b r a c a d a b r a
ok
1 2 3 4 5 6 7 8 9 10 | -module(string_pyramid).
-import(lists, [flatmap/2, foreach/2, nthtail/2, seq/2]).
-import(string, [centre/2, len/1, strip/3]).
-export([string_pyramid/1]).
string_pyramid(Str) ->
L1 = [nthtail(len(Str) - X, Str) || X <- seq(1, len(Str))],
L2 = [flatmap(fun(Y) -> [Y, " "] end, X) || X <- L1],
L3 = [centre(strip(X, both, " "), len(Str) * 2 - 1) || X <- L2],
foreach(fun(X) -> io:format("~s~n", [X]) end, L3).
|
再帰的に処理しつつpyramid関数の引数の数を変えないために, 新たにrecurs関数を定義しました.
1 2 3 4 5 6 7 8 | def pyramid(str)
def recurs(str, i, spc = ' ')
puts "#{spc*i}#{str[i..-1].split('').join(spc)}"
recurs(str, i-1) if i >= 1
end
recurs(str, str.size-1)
end
pyramid("abracadabra")
|
1 2 3 4 5 6 7 | let pyramid s =
let len = String.length s in
for spc = (len-1) downto 0 do
print_string (String.make spc ' ');
String.iter (Printf.printf "%c ") (String.sub s (spc) (len-spc));
print_newline ();
done;;
|
遅レスですが#160を参考につくってみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <stdio.h>
#include <string.h>
void pyramid(char* p) {
int i, j, len;
len = strlen(p);
for(i=0; i<len; i++) {
printf("%*c ", len-i, p[len-i-1]);
for(j=len-i; j<=len; j++) printf("%c ",p[j]);
printf("\r\n");
}
}
int main(int argc, char **argv) {
argc > 1 ? pyramid(argv[1]) : ;
pyramid("hoge");
pyramid("abracadabra");
return 0;
}
|
工夫すればもう少し簡潔に書けそうですが、表示速度が遅い点に目をつぶれば、ひとまず
目的は達したと言えそうです。(引数に半角空白が含まれる場合には対応していません。)
e.g.
C:\>pyramid abracadabra
a
r a
b r a
a b r a
d a b r a
a d a b r a
c a d a b r a
a c a d a b r a
r a c a d a b r a
b r a c a d a b r a
a b r a c a d a b r a
遅延環境変数展開を利用しているので、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 | :: pyramid.bat
@echo off
setlocal enabledelayedexpansion
set l=0
set n=0
set s=
set t=
if "%1" == "" (echo %~n0 [STRING] & goto :EOF)
call :length %1 l
for /l %%i in (1,1,%l%) do (
set s=
set /a n=%l%-%%i
for /l %%j in (!n!,-1,1) do set s=!s!
for /l %%j in (%%i,-1,1) do (
set /a n=%l%-%%j
call :substr %1 !n! 1 t
set s=!s!!t!
if %%j gtr 0 set s=!s!
)
echo !s!
)
endlocal
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
:substr
setlocal enabledelayedexpansion
set t=%1
set t=!t:~%2,%3!
endlocal & set %4=%t%
goto :EOF
|
なんか美しくないですが...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | %!PS
/pyramid { % (string) pyramid -
dup length 1 sub dup -1 0 {
dup { ( ) print } repeat
1 2 index {
2 index exch 1 getinterval print ( ) print
} for
( ) =
} for
} def
% ------- Test Code --------
(hoge) pyramid
(abracadabra) pyramid
|
あらかじめ最下段の文字列を作っておいてから、
オシリからアタマへ向かって表示部分を伸ばしつつ、
各行を printf で表示しています。
実行例:
$ ./pyramid hoge
e
g e
o g e
h o g e
$ ./pyramid abracadabra
a
r a
b r a
a b r a
d a b r a
a d a b r a
c a d a b r a
a c a d a b r a
r a c a d a b r a
b r a c a d a b r a
a b r a c a d a b r a
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 | #include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv){
int i, len;
char *srcstr, *cpstr, *s, *d, format[15];
if(argc < 2) exit(1);
srcstr = argv[1];
len = strlen(srcstr);
cpstr = malloc(len * 2);
if(!cpstr) exit(1);
s = srcstr + len - 1;
d = cpstr + len * 2;
*d-- = '\0';
while(s != srcstr){
*d-- = *s--;
*d-- = ' ';
}
*d = *s;
d = cpstr + len * 2 - 1;
for(i = 0; i < len; i++, d -= 2){
sprintf(format, "%%%ds\n", len + i);
printf(format, d);
}
free(cpstr);
return 0;
}
|
対象文字列はテンプレートパラメタ txt で渡してください。
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 | <xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
>
<xsl:param name="txt" as="xs:string" />
<xsl:output method="text" />
<xsl:template match="/" >
<xsl:variable name="chars" as="xs:string*">
<xsl:for-each select="fn:string-to-codepoints($txt)">
<xsl:sequence select="fn:codepoints-to-string((.))" />
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="1 to fn:count($chars)">
<xsl:variable name="wscount" as="xs:integer"
select="fn:count($chars)-." />
<xsl:for-each select="1 to $wscount" >
<xsl:text> </xsl:text>
</xsl:for-each>
<xsl:value-of select="fn:subsequence($chars, $wscount+1)" />
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
|
今更ですが。追加のモジュールを使わずに。
1 2 3 4 5 6 7 8 9 | pyramid s =
take ln $ [(replicate (ln - l) ' ') ++ (drop ((ln - l) * 2) ss) | l <- [1..]]
where
ln = length s
ss = concat [[x,' '] | x <- s]
main = do
mapM_ putStrLn $ pyramid "hoge"
mapM_ putStrLn $ pyramid "abracadabra"
|
Whitespaceで。
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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
.
|
SQL Server 2008 で確認しました。
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 | WITH
Input(id, str) AS (
SELECT 1, 'hoge'
UNION ALL SELECT 2, 'abracadabra'
)
, ExpandsSrc(id, str, input_str) AS (
SELECT
id
, CAST(LEFT(str, 1) + ' ' AS varchar(max))
, SUBSTRING(str, 2, LEN(str))
FROM
Input
UNION ALL
SELECT
id
, str + LEFT(input_str, 1) + ' '
, SUBSTRING(input_str, 2, LEN(input_str))
FROM
ExpandsSrc
WHERE
input_str <> ''
)
, Expands(id, str) AS (
SELECT id, str FROM ExpandsSrc WHERE input_str = ''
)
, Pyramid(id, i, str, input_str) AS (
SELECT
id
, 1
, str
, SUBSTRING(str, 3, LEN(str))
FROM
Expands
UNION ALL
SELECT
id
, i + 1
, SPACE(i) + input_str
, SUBSTRING(input_str, 3, LEN(input_str))
FROM
Pyramid
WHERE
input_str <> ''
)
SELECT str FROM Pyramid
ORDER BY id, i DESC
|
凡庸な解でして・・・
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | object MojiPira {
def main(args : Array[String]) : Unit = {
val moji = args(0)
val m = moji.length
val fn = (m:Int,x:String) => println( x+" "*( 2*m - 1 - x.length ) )
mojiPira(m).foreach(fn(m,_))
def mojiPira(n:Int) :List[String] = {
if( n==1 ){
return List(moji(0).toString)
}else{
val tail = moji(n-1)
val prev = mojiPira(n-1)
var now = List(" "*prev.length + tail)
for(a<-prev) now = now ::: (a + " " + tail)::Nil
return now
}
Nil
}
()
}
}
|
文字列をリストに変換せずにやってみた。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | object MojiPira {
def main(args : Array[String]) : Unit = {
pyramid(args(0))
}
def pyramid(moji:String) = {
val m = moji.length
mojiPira(" "*(m-1),"",moji.reverse){print _}
}
def mojiPira(mergin:String,prevPrn:String,s:String)(prn:String=>Unit) : Unit = {
val prnStr = if (prevPrn=="") ""+s(0) else s(0) + " " + prevPrn
prn(mergin + prnStr + mergin + "\n")
if( mergin!="" )
mojiPira(mergin.substring(1),prnStr,s.substring(1))(prn)
}
}
|
ワンライナー系として。
1 | "abracadabra".inject([]){r,i->[' '*r.size()+i]+r.collect{it+' '+i}}.each{println it}
|
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 | using System;
using System.Linq;
namespace Sample {
class Program {
static void Main(string[] args) {
Pyramid("hoge");
Pyramid("abracadabra");
Console.ReadLine();
}
static void Pyramid(string s) {
int length = s.Length;
for (int n = 0; n < length; n++) {
// 左側の空白を表示
int spCount = length - n - 1;
Console.Write(new string(' ', spCount));
// 右側の文字部分を表示
var ls = s.Skip(spCount);
foreach (var c in ls)
Console.Write(c + " ");
Console.WriteLine();
}
}
}
}
|






にしお
#3408()
Rating1/1=1.00
>>> pyramid("hoge") e g e o g e h o g e>>> pyramid("abracadabra") a r a b r a a b r a d a b r a a d a b r a c a d a b r a a c a d a b r a r a c a d a b r a b r a c a d a b r a a b r a c a d a b r a[ reply ]