Распечатать арку по возрастанию / убыванию числа


28

Я подумал, что «арка» - лучший способ описать эту схему чисел:

1234567887654321
1234567  7654321
123456    654321
12345      54321
1234        4321
123          321
12            21
1              1

Формально определенная каждая строка состоит из цифр от 1 до 1 9-n, (n-1)*2пробелов и цифр 9-nот 1 (где nтекущая строка).

Ваша задача - написать, используя кратчайший код, небольшой скрипт / программу, которая печатает вышеприведенный шаблон с учетом следующих ограничений:

  1. Вы не можете жестко закодировать весь шаблон. Вы можете жестко закодировать только одну строку шаблона.
  2. Ваша программа должна напечатать новую строку (любую комбинацию \nили \r) в конце каждой строки.

На старт, внимание, марш!


1
Дополнительная маленькая хитрость будет доступна с верхней строкой, так 123456787654321как она равна 11111111^2 ;-)
Егор Скриптунов

3
@EgorSkriptunoff 11111111^2 == 123465787654321 != 1234567887654321(обратите внимание на повторение 8)
Боб

Это своего рода перевернутая печать этого алмаза
Питер Тейлор

6
Это выглядит скорее как занавес .
Волатильность

Ответы:




9

APL (18)

k,⌽k←↑↑∘(1↓⎕D)¨⌽⍳8

Объяснение:

  • 1↓⎕D: строка цифр ("0123456789") минус первый элемент
  • ↑∘(1↓⎕D)¨⌽⍳8: выберите первые [8..1] символы («12345678», «1234567» ...)
  • : форматирование в виде матрицы (заполнение неиспользуемых символов пробелами)
  • k,⌽k←: сохранение kи отображение с kпоследующим вертикальным отражениемk

4

Рубин: 61 50 символов

s="87654321";s.chars{|c|puts s.reverse+s;s[c]=" "}

Образец прогона:

bash-4.2$ ruby -e 's="87654321";s.chars{|c|puts s.reverse+s;s[c]=" "}'
1234567887654321
1234567  7654321
123456    654321
12345      54321
1234        4321
123          321
12            21
1              1

4

Befunge - 3 х 18 = 54

Я чувствовал, что должен был что-то сделать с befunge, прошло слишком много времени с тех пор, как я последний раз использовал это. Эта проблема показалась наиболее подходящей для языка.

Это ужасно медленно из-за цикла печати, который занимает около 8 действий на символ (стили подсчета отличаются).

80v >#v"12345678"<
>5 *^ >,#$:_$:1-:v
^2< 0p0+7\*48\_@#<

4

JavaScript, 71

s='1234567887654321',i=10;while(--i)console.log(s=s.split(i).join(' '))

s="1234567887654321";for(i=10;--i;)console.log(s=s.split(i).join(" "))для 70 символов, @SteveWorley
WallyWest

3

С, 83 символа

main(a,b,n){
    for(a=12345678,n=1e8,b=n-a-1;a;a/=10)
        printf("%-8d%8d\n",a,b),
        b%=n/=10;
}

3

Python 2, 75 62

Это не превзойдет ответ Волатильности, но вот другой подход, использующий изменяемые строки python ( bytearray):

s=bytearray('1234567887654321')
for i in range(8):s[8-i:8+i]=i*'  ';print s

редактировать

Я нашел более короткую версию, используя str.replace:

s='1234567887654321'
for c in s[8:]:print s;s=s.replace(c,' ')

3

Perl, 41

плюс -Eвыключатель. Всего символов в командной строке: 50

требуется как минимум perl5, версия 10.

perl -E'say@!=1..8-$_,$"x(2*$_),reverse@!for-0..7'

Я бы сказал, что это 42 из-за того, что стандартный просмотр -Eявляется однобайтовым дополнением к программе.
Timtech

3

Mathematica 92 85 67 54 51

Метод № 1 : (54 символа) Создает массив, используя номер строки, столбец # и расстояние от левого-правого края.

Grid@Array[If[#2<9,#2,17-#2]/.x_/;x+#>9:>" "&,{8,16}]

Метод № 2 : (67 символов).

Print@@@Table[Join[k = PadRight[Range@i, 8, " "], Reverse@k], {i, 8, 1, -1}];

Метод № 3 : (85 символов) Выборочно заполнить каждую строку массива.

Начните со списка из 8 пробелов. Заменить позиции 1 и 16 на «1»; заменить "2" в положениях 2 и 15 и т. д.

p = 0; q = 16;
Print @@@Reverse@Rest@NestList[ReplacePart[#, {++p -> p, q-- -> p}]&,Array[" "&,q], 8];

Метод № 4 : (86 символов) Выборочно очищать каждую строку массива.

p=8;q=9;
Print@@@NestList[ReplacePart[#,{p---> " ",q++-> " "}]&,Join[k=Range@8,Reverse@k],7];

Метод № 5 : Использование строк (92 символа)

p=8;s="12345678";
Print[#,StringReverse@#]&/@NestList[StringReplace[#,ToString@p-- ->  " "]&,s,7];

Этот новый слик! Я бы снова +1, если бы мог. :-) Кстати, вы можете бросить (), и заменить #1на #:Grid@Array[If[#2<9,#2,17-#2]/.x_/;x+#>9:>" "&,{8,16}]
Mr.Wizard

Спасибо за советы. Да, Arrayиногда можно создавать хорошие таблицы без необходимости добавлять итераторы.
DavidC

3

PHP, 68

(Вдохновленный ответом HamZa)

for($n=8;$n;$r[]=$n--)echo str_replace($r," ","1234567887654321\n");

Воспроизводит тот факт, что PHP str_replace может принять массив для поиска и строку для замены, он заменит каждый элемент в массиве с данной строкой. После каждой итерации текущий номер добавляется в массив поиска, удаляя его из следующего цикла.

Пример кода в действии: http://ideone.com/9wVr0X


хе-хе приятно +1
ХамЗа

не кажется, чтобы поставить нужное количество пробелов в середине, хотя
Натан Хейфилд

@nathanhayfield: Как так? В первой строке 0 пробелов, во второй 2, затем 4, 6, 8 и т. Д.
г-н Лама

не когда я запускал его на writecodeonline.com/php
Натан Хейфилд

Это потому, что вывод не был обернут в <pre>теги. Когда интерпретируется как HTML-текст, пробелы свернуты и новые строки игнорируются, но если вы проверите источник, вы увидите иначе.
Г-н Лама

3

Marbelous 165

@0
08
>0
LN
--
@0
:LN
}0}0}0}0
..SAPSSD0A
{0
:PS
}0
~~09
..//
<<@0
\\>0
&0//
--@1
@020
&0/\&0
@1
:SA
@0
}0
>0!!
--00@1
@0++//
+O/\@1
+O
:SD
}0@0
\\>0\/
--/\+O
@0..+O

псевдокод:

MB():
    for x in 8..1:
        LN(x)
LN(x):
    SA(x)
    PS(x)
    SD(x)
    print "\n"
PS(x):
    print " "*(8-x)*2
SA(x):
    for n in 1..x:
        print n
SD(x):
    for n in x..1:
        print n

2

Python 2.x - 73 65 63 61 символ

c=1;s='87654321'
while c<9:print s[::-1]+s;s=' '*c+s[c:];c+=1


2

К, 28

-1_a,'|:'a:8$'{-1_x}\,/$1+!8

,

k)-1_a,'|:'a:8$'{-1_x}\,/$1+!8
"1234567887654321"
"1234567  7654321"
"123456    654321"
"12345      54321"
"1234        4321"
"123          321"
"12            21"
"1              1"

Вы могли бы обобщить это для 36: {-1_a,'|:'a:(#*m)$'m:{-1_x}\,/$1+!x}

k){-1_a,'|:'a:(#*m)$'m:{-1_x}\,/$1+!x} 5
"1234554321"
"1234  4321"
"123    321"
"12      21"
"1        1"
q)k){-1_a,'|:'a:(#*m)$'m:{-1_x}\,/$1+!x} 15
"123456789101112131415514131211101987654321"
"12345678910111213141  14131211101987654321"
"1234567891011121314    4131211101987654321"
"123456789101112131      131211101987654321"
"12345678910111213        31211101987654321"
"1234567891011121          1211101987654321"
"123456789101112            211101987654321"
"12345678910111              11101987654321"
"1234567891011                1101987654321"
"123456789101                  101987654321"
"12345678910                    01987654321"
"1234567891                      1987654321"
"123456789                        987654321"
"12345678                          87654321"
"1234567                            7654321"
"123456                              654321"
"12345                                54321"
"1234                                  4321"
"123                                    321"
"12                                      21"
"1                                        1"

2

Javascript, 67 символов

Вдохновленный ответом steveworley (я бы прокомментировал, если бы мог):

Фрагмент кода

a='1234567887654321\n',b='',c=10;while(--c)b+=a=a.split(c).join(' ')
<a href="#" onclick="javascript:document.getElementById('output').innerHTML = b;">Display</a>
<pre id="output">...</pre>

Наличие последней новой строки действительно следует правилам.

обновление: сократить 2 символа, удалив скобки (приоритет оператора) и 1, удалив ненужный пробел

Мне показалось, что это меня обманывает, потому что независимо от того, сколько разных способов я пытался сократить или упростить, не жестко кодируя сегмент кода, длина оставалась неизменной до тех пор, пока я не применил правило «Я думаю, что это количество», написанное ниже.

(Если печать считается тем, что возвращается при выполнении в консоли Chrome)


Это не похоже на другой ответ, цифры не выровнены по правому столбцу.
AL

@AL Предупреждение не нужно, если вы читаете, какой выход выходит из созвездия между прочим.
Sophiα2329

Чтобы выровнять правый столбец, в строковом аргументе соединения должен быть 1 пробел вместо 2. С двумя пробелами это правильно выровнено в основанном на chrome предупреждении браузера.
Qwertiy

Я обновил ваш пост (редактирование должно быть принято), чтобы отобразить результат во фрагменте без предупреждения JS, в этом случае требуется только один пробел.
AL

2

Brainfuck: 542 байта

-[----->+<]>--.+.+.+.+.+.+.+..-.-.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.+.+.+[-->+<]>++++..----[->++<]>-.-.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.+.[-->+<]>+++++....-----[->++<]>.-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.+.--[--->++<]>--......-----[->++<]>-.-.-.-.-.>++++++++++.[->+++++
<]>-.+.+.+.-[--->++<]>--........++[-->+++<]>+.-.-.-.>++++++++++.[->+++++
<]>-.+.+.[--->++<]>--..........++[-->+++<]>.-.-.>++++++++++.[->+++++
<]>-.+.--[--->++<]>............[-->+++<]>++.-.>++++++++++.[->+++++
<]>-.-[--->++<]>..............[-->+++<]>+.

1

Математика , 59

61 используя мои собственные идеи:

Grid[Clip[#~Join~Reverse@#&@Range@8,{1,9-#},{," "}]&~Array~8]

Или 59, заимствуя из ответа Давида:

Grid@Array[Join[k=PadRight[Range[9-#],8," "],Reverse@k]&,8]

Я только что спас 4 символа, используя Grid, вдохновленный вашей записью.
DavidC


1

Хаскелл, 84

Отправная точка для улучшения

mapM_ putStrLn[let l=take(8-i)"12345678"++replicate i ' 'in l++reverse l|i<-[0..7]]

Скорее всего, часть будет заключаться в том, чтобы освободить эту l++reverse lточку зрения, что позволит нам избавиться от letзаявления, но я смогу выяснить ap, что требует импорта.


1

PostScript: 105 символов

Обработка строк не проста в PS, но может сделать относительно простой код:

0 1 7{(1234567887654321)dup
8 3 index sub(              )0 6 -1 roll 2 mul getinterval putinterval =}for

Немного более длинная версия с 120 символами, но может генерировать различные числовые арки, заменяя 8 в начале второй строки любым числом в диапазоне от 1 до 9:

/D{dup}def/R{repeat}def/P{=print}def
8 D -1 1{1 1 index{D P 1 add}R pop 2 copy sub{(  )P}R D{D P 1 sub}R pop()=}for pop

Приятно видеть, что я не единственный, кто любит PostScript.
AJMansfield


1

К 20

{x,'|:'x:|x$,\$1+!x}    

q)k){x,'|:'x:|x$,\$1+!x}8    
"1234567887654321"    
"1234567  7654321"    
"123456    654321"    
"12345      54321"    
"1234        4321"      
"123          321"    
"12            21"    
"1              1"    

1

TSQL, 148

Изменить: до 148 с предложением Манатворка и настроить ORDER BY.

Удобочитаемый:

WITH t AS(
    SELECT 1n, CAST(1 AS VARCHAR(MAX)) o
 UNION ALL
    SELECT n+1,o+CHAR(n+49)
    FROM t
    WHERE n<8
)
SELECT o  + SPACE(16-2*n) + REVERSE(o)
FROM t
ORDER BY 1 DESC

Golfed:

WITH t AS(SELECT 1n,CAST(1AS VARCHAR(MAX))o UNION ALL SELECT 1+n,o+CHAR(n+49)FROM t WHERE n<8)SELECT o+SPACE(16-2*n)+REVERSE(o)FROM t ORDER BY 1DESC

Выход:

1234567887654321
1234567  7654321
123456    654321
12345      54321
1234        4321
123          321
12            21
1              1

1
Хороший. Но не могли бы вы опубликовать его также в формате, в котором вы насчитали 153 символа? Во всяком случае, вы можете сэкономить 2 символа, используя числовые 1вместо строки, '1'где вы сразу же в castнего varchar. Это дает мне 149 символов: with t as(select 1n,cast(1as varchar(max))o union all select n+1,o+char(n+49)from t where n<8)select o+space(16-2*n)+reverse(o)from t order by o desc.
Манатворк

@manatwork: я не мог воспроизвести число 153, потому что я продолжал снижаться. Применил ваше предложение, хотя. Благодарность!
comfortablydrei

1

Хаскелл, 79

r n x|x>n=' '|True=x
t="87654321"
main=mapM(putStrLn.(`map`("12345678"++t)).r)t

Это работает путем замены символов> n на ' ', где символы n получены из "87654321" (что является хвостом строки для выполнения подстановки).


1

PHP: 61 символ (или 60 символов, если вы замените \ n реальной строкой ASCII)

(Вдохновленный ответами GigaWatt и HamZa)

for($n=9;$n;$r[$n--]=" ")echo strtr("1234567887654321\n",$r);

http://ideone.com/FV1NXu


1

PowerShell: 38

Гольф-код

8..1|%{-join(1..$_+"  "*(8-$_)+$_..1)}

Прохождение

8..1|%{... }передать целые числа от 8 до 1 в цикл ForEach-Object.
-join(... )объединяет вывод вложенного кода в одну строку без разделителей.
1..$_выводит целые числа по возрастанию от 1 до текущего целого числа в цикле.
+" "*(8-$_)добавляет к выходу двойной пробел, умноженный на разницу между 8 и текущим целым числом.
+$_..1добавляет целые числа, убывающие от текущего целого числа до 1, к выводу.


1

Javascript с лямбдами, 147

(s="12345678")[r="replace"](/./g,i=>s[r](RegExp(".{"+(i-1)+"}$"),Array(i*2-1).join(" ")))[r](/\d{1,8} */g,m=>m+(Array(m%10+1).join(m%10+1)-m)+"\n")

Может быть проверено в Firefox.



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.