Narysuj Alfabet Sawtooth

42

Prosty dzisiaj. Napisz najkrótszy program, który rysuje „alfabet piłokształtny”, podając dodatnią liczbę całkowitą dla wysokości. Musisz wpisać nazwę swojego języka programowania, gdy dojdziesz do litery, od której się zaczyna.

Na przykład, jeśli Twoim językiem jest Python, a dane wejściowe to 1dane wyjściowe powinny być:

ABCDEFGHIJKLMNOPythonQRSTUVWXYZ

Jeśli wejście jest 2wyjściem powinno być:

 B D F H J L N Python R T V X Z
A C E G I K M O      Q S U W Y

Jeśli wejście jest 4wyjściem powinno być:

   D     J     Python     V
  C E   I K   O      Q   U W
 B   F H   L N        R T   X Z
A     G     M          S     Y

Notatki

  • A zawsze zaczyna się w lewym dolnym rogu.
  • Dane wejściowe mogą być przesyłane przez standardowe wejście lub wywołanie funkcji lub podobnie. Wyjście na standardowe wyjście.
  • Powyższe dane wejściowe 26nie muszą działać.
  • Brak spacji końcowych.
Hobby Calvina
źródło
9
Czy dozwolone są języki programowania z nazwami jednoliterowymi? (C, J, K itp.)
isaacg
@isaacg Pewnie. Wyobrażam sobie, że może być w nich łatwiej.
Calvin's Hobbies
1
Czy dane wejściowe można po prostu przechowywać w zmiennej?
Martin Ender
@ MartinBüttner Tak, w porządku.
Calvin's Hobbies
13
A tak przy okazji, to nie jest fala piłokształtna, to fala trójkątna: P
qwr

Odpowiedzi:

14

jeśli n ma wysokość:

Kody ucieczki C +: 81

x;main(y){for(y=n--;x<26;x++)printf("\033[%d;%dH%c",n?x/n&1?y++:y--:y,x+1,x+65);}

C: 110

x;char a[702]={[0 ...701]=32};main(y){for(y=--n;x<26;a[x*27-1]=10)a[27*(n?x/n&1?y++:y--:y)+x]=x+++65;puts(a);}
bebe
źródło
5
Przyznaję się do porażki. Co do licha. : D
Martin Ender
Czy mogę prosić o instrukcje kompilacji? ccdaje błąd „<bebe.c: 1: 17: error: 'n' undeclared (pierwsze użycie w tej funkcji)”.
manatwork
2
cóż, jest o wiele gorzej niż się wydaje. po pierwsze drugi zawiera końcowe spacje, po drugie oba zależą od tego, że njest to zmienna globalna ustawiona na wybraną przez ciebie liczbę (jak wcześniej pytał Martin).
bebe
Och, więc muszę podać n w każdy możliwy sposób. Lol. Wciąż pod wrażeniem.
manatwork
19

C 134

n,m,c,p;
main(r){
for(scanf("%d",&n),m=--n?n*2:1;n+r--;puts(""))
for(c=-1,p=1;c++<25;)
p+=(c-n-r)%m*((c-n+r)%m)?1:1-printf("%*c",p,c+65);
}

Kompiluje na gcc z kilkoma ostrzeżeniami. Nowe linie nie są uwzględniane w liczbie znaków.

122 znaki, jeśli dane wejściowe są już zapisanen .

Dzięki user2992539 , tolos i edc65 za ulepszenia.

grc
źródło
3
Możesz użyć puts("")zamiast printf("\n").
Somnium
2
Oszczędź 4 znaki p-=(c-n+r)%m*((c-n-r)%m)?0:printf("%*c",p,c+65);zamiastif((c-...
1
Przepraszamy za poprzedni (usunięty) komentarz. Myliłem się. Granie ze znakami i nadużywanie faktu, że pierwszy argument main wynosi 1, jeśli nie ma parametrów: 134n,m,c,p; main(r){ for(scanf("%d",&n),m=--n?n*2:1;n+r--;puts("")) for(c=-1,p=1;c++<25;) p+=(c-n-r)%m*((c-n+r)%m)?1:1-printf("%*c",p,c+65); }
edc65
13

TI-BASIC - 148 bajtów (nieprzetworzony tekst), 186 bajtów (grafika)

W odpowiedzi na OP, wspaniały TI-83 (i nowsze) ma rozmiar 16 x 8 (tylko używając standardowego dużego tekstu) lub rozmiar 94 x 62 pikseli (który z małym tekstem jest wart około 10 linii ).

To jest mały problem (do którego chciałbym wyjaśnienia). Interpretator nie może zignorować impozycji wielkości; innymi słowy, gdybyśmy próbowali ustawić wysokość piły na 20, dałoby to błąd uniemożliwiający pełne wykonanie kodu. I może napisać kod, który w nieskończonym środowiska, tworzenia prawidłowego wyjścia, oprócz tego, że nie będzie działać na maszynie.

Mówiąc to, przedstawiam wam (uruchomione) wersje programów. Wszystkie zależą od ustawienia zmiennej Nw żądanej wysokości w liniach przed uruchomieniem:

  • Podejście surowego tekstu

    :ClrHome
    :"ABCDEFGHIJKLMNOPQRSTI-BASICUVWXYZ"→Str1
    :8→R
    :For(C,1,16
    :If N=1
    :Then
    :0→F
    :Else
    :If R<2 or 10-R>N
    :1→F
    :If R>7
    :-1→F
    :End
    :If C≠20
    :Then
    :Output(R,C,sub(Str1,C,1
    :Else
    :Output(R,C,sub(Str1,C,8
    :C+7→C
    :End
    :R+F→R
    :End
    

    W celu dokonania tej pracy niezależnie od terminalu, zmiany For(C,1,16do For(C,1,33i zdjąć górną sprawdzanie zakresu ( R<2 or). Oto wynik z 5→N:

    enter image description here

  • Podejście graficzne (może to również wymagać AxisOffprzejrzystości)

    :ClrDraw
    :N*6→N
    :"ABCDEFGHIJKLMNOPQRSTI-BASICUVWXYZ"→Str1
    :57→R
    :For(C,1,56
    :If N=6
    :Then
    :0→F
    :Else
    :If R<7 or 64-R>N
    :6→F
    :If R>51
    :-6→F
    :End
    :If C≠20
    :Then
    :If C>50
    :Then
    :Text(R,C,sub(Str1,C-23,1
    :Else
    :Text(R,C,sub(Str1,C,1
    :End
    :Else
    :Text(R,C,sub(Str1,C,8
    :C+30→C
    :End
    :R+F→R
    :End
    

    Ten działa OK, z dwoma drobnymi dziwactwami. Wysokość nadal stanowi problem, chociaż szerokość nie. Nie rozstawiałem jednak liter, więc w niektórych przypadkach (gdy list zaczyna się podnosić lub opadać z piły), litery mogą zostać odcięte przez ich następców. Aby działał niezależnie od terminala, usuń górną granicę check ( R<7 or). Następnie następuje wykres:

    enter image description here

Doktoro Reichard
źródło
Teraz mają do tego portu do mojego Kalkulator graficzny
Liam McInroy
Szybki komentarz: Zamiast tego 0→Fmożesz zrobić, Delvar Fktóry oszczędza 1 bajt po tokenizacji. Ponadto jestem pewien, że możesz uwzględnić czynnik wyjściowy / tekst pod koniec dzięki wbudowanemu warunkowi testu logicznego dla współrzędnej, a dla C+7→Cnapisać go w krótkim, jeśli (nie wtedy / jeszcze / koniec)
Adriweb
11

Pure Bash (bez coreutils), 181 bajtów

m=$1
for l in A Bash {C..Z};{
((m))||s=++
((m>$1-2))&&s=--
for((m=$1==1?1:m,m$s,i=0;i<$1;i++));{
((i-m))&&a[i]+=${l//?/ }||a[i]+=$l
}
}
shopt -s extglob
printf %s\\n "${a[@]%%+( )}"

Wynik:

Rurociągi w cat -Ecelu udowodnienia, że ​​nie ma końcowych linii.

$ ./sawtooth.sh 1 | cat -E
ABashCDEFGHIJKLMNOPQRSTUVWXYZ$
$ ./sawtooth.sh 5 | cat -E
       E       M       U$
      D F     L N     T V$
     C   G   K   O   S   W$
 Bash     H J     P R     X Z$
A          I       Q       Y$
$ 
Cyfrowa trauma
źródło
10

JavaScript (ES6) 231 244

Edytuj poprawkę, trochę zmiany kolejności i inny sposób zarządzania wysokością == 1
Ponadto zmieniono na funkcję, ponieważ jest to dozwolone przez OP, więc nie pytaj () o dane wejściowe

Brak zmian w ogólnym algorytmie, który prawdopodobnie NIE jest najlepszy do tego wyzwania

F=h=>{for(p=s=[i=z=b=t=''];++p<h;)i=1,z=b=' ',s[p]=t;for(p=--h,k=64;++k<91;)s[p]+=t+String.fromCharCode(k),k-74||(s=s.map((x,q)=>x+(p-q?'         ':'avascript'))),p-=i,p<0|p>h?(i=-i,p-=i+i,t=z,b=t+t):t+=b;console.log(s.join('\n'))}

Wyjaśniono

F=h=>{
  // row in s for output must be initialized to ''. In the same step I make other initializations
  for(p=s=[i=z=b=t='']; ++p < h;) // initialize for height 1, all increment and spacing can be null
    i=1,z=b=' ',s[p]=t; // the for body is entered only if height > 1, initializing spacing and increment to the right values
  for(p=--h,k=64;++k<91;)
    s[p]+=t+String.fromCharCode(k),
    k-74||(s=s.map((x,q)=>x+(p-q?'         ':'avascript'))), // if 'J' modify each line of output adding the name or spacing
    p-=i,p<0|p>h?(i=-i,p-=i+i,t=z,b=t+t):t+=b; // index bouncing
  console.log(s.join('\n'))
}

Przykłady

1

ABCDEFGHIJavascriptKLMNOPQRSTUVWXYZ

3 idzie w górę

  C   G            K   O   S   W
 B D F H Javascript L N P R T V X Z
A   E   I            M   Q   U   Y

4 na górze

   D     Javascript     P     V
  C E   I          K   O Q   U W
 B   F H            L N   R T   X Z
A     G              M     S     Y

7 spada

      G                    S
     F H                  R T
    E   I                Q   U
   D     Javascript     P     V
  C                K   O       W
 B                  L N         X Z
A                    M           Y
edc65
źródło
9

JAVA (393)

Jak zawsze świetny język do gry w golfa:

public class P{public static void main(String[]a){int h=Integer.valueOf(a[0]);String x="ABCDEFGHIJKLMNOPQRSTUVWXYZ";String[]l=new String[h];Arrays.fill(l,"");int i=h-1;int d=-1;for(char c:x.toCharArray()){for(int n=0;n<l.length;n++){String k=(n==i)?(c=='J')?"Java":c+"":(c=='J')?"    ":" ";l[n]+=k;}if(i==0&&d==-1)d=1;if(i==h-1&&d==1)d=-1;if(h>1)i+=d;}for(String s:l){System.out.println(s);}}}
Thomas Rüping
źródło
2
Niestety, zapomniałeś importu dla java.util.Arrays;. :-(
Justin
Ale możesz poprawić swój kod: wyeliminuj String x="ABC...Z";i zamień for(char c...nagłówek pętli na for (char c=65;++c<91;){, Uwielbiam znaki w Javie =)
flawr
Dalsze można zastąpić c=='J'z c==74oszczędza kolejne dwa bajty w sumie.
flawr
2
Jestem pewien, że możesz zrobić jeszcze lepiej, jeśli skondensujesz, jeśli użyjesz niektórych XOR dla tych instrukcji if, ale tutaj moja ulepszona wersja: (325) public class p{public static void main(String[]a){int h=Integer.valueOf(a[0]),i=h-1,d=-1,n;String[]l=new String[h];for(n=0;n<h;l[n++]="");for(char c=64;++c<91;){for(n=0;n<h;n++){String k=n==i?c==74?"Java":c+"":c==74?" ":" ";l[n]+=k;}if(i==0&d==-1)d=1;if(i==h-1&d==1)d=-1;i+=h>1?d:0;}for(String s:l)System.out.println(s);}}@Quincunx: koniec potrzeby import.util.Arrays; =)
wada
9

Ruby, 112 bajtów

o="#{' '*29}
"*h
26.times{|i|o[(h-i%(h<2?1:2*h-2)-1).abs*30+i+(i>17?3:0)]=(i+65).chr}
puts o.gsub('R   ','Ruby')

Oczekuje, że dane wejściowe zostaną zapisane h.

Daj mi znać, jeśli wymaga to wyjaśnienia.

Martin Ender
źródło
Bardzo niewielkie, ale później możesz usunąć miejsce %.
Calvin's Hobbies
@ Calvin'sHobby Hobby, nie ufałem podkreśleniu tam mojej składni: D. Naprawię to później.
Martin Ender
Można wymienić puts o...z $><<o....
Jordan
6

J: 75 bajtów

NB. without IO |:26([:u:65+i.@[)`(($(,|.@}.@}:)@i.)<"1@,.i.@[)`(' '$~,~)}5
2(1!:2)~|.26([:u:65+i.@[)`(($(,|.@}.@}:)@i.)<"1@,.i.@[)`(' '$~,~)}".1!:1[1

Korzystając ze wspaniałej koniunkcji Amend . Jak zwykle IO jest brzydkie i niezgrabne, nie wchodząc w szczegóły. Podstawowe rozwiązanie wymaga 3 gerunds (rodzaj czasownika rzeczownikowego (aka. Funkcja)):

  • a) generowanie alfabetu
  • b) generowanie wskaźników
  • c) generowanie macierzy w celu poprawek

    x (a bc}) y

a) to dość trywialne wyszukiwanie w tabeli ascii

c) jest jeszcze bardziej trywialny

b) jest interesujący. Morale jest takie, że wskaźniki poziome powinny zaczynać się od zera do y-1 i wracać w dół, powtarzając to 26 razy. Na przykład. dla y == 4:

0 1 2 3 2 1 0 1 2 3 2 1 ...

Wdrożenie tego daje b):

($(,|.@}.@}:)@i.) <"1@,. i.@[)       NB. is equivalent too
(tine0 tine1 tine2)                  NB. a fork with tines defined as
tine0 =: 
  hook0 =: hook0_0 hook0_1           NB. a dyadic hook: x (g h) y -: x g h y
     hook0_0 =: $                    NB. reshape
     hook0_1 =: (hook1_0 hook1_1)@i. NB. do hook1 after making 0-y
       hook1_0=: ,                   NB. append to self
       hook1_1=: |.@}.@}:            NB. rotated version of y after beheading and curtailing
tine2 =: i.@[                  NB. generate 0-x
tine1 =: <"1@,.                NB. glue together coordinates.

I o tak, przydatny fakt: J ma na imię ... „J”.

jpjacobs
źródło
Czy warto skorzystać z poprawki? Wydaje mi się, że łatwiej jest powiedzieć coś 3 :'|:(26$1+(i.1=y),}:|i:<:y)|.@{."+u:65+i.26'brzydkiego. W tym rozwiązaniu brzydkie jest 8 znaków o specjalnej wysokości 1, ale prawdopodobnie można to nieco skrócić.
b_jonas
Dzieki za sugestie! Twoja jest rzeczywiście znacznie krótsza, a poprawka jest prawdopodobnie przesadą. Skoro jest tak inaczej, może sam chciałbyś opublikować to jako rozwiązanie?
jpjacobs
Specyfikacja mówi „brak spacji końcowych”, a moje rozwiązanie drukuje spacje końcowe.
b_jonas
5

R (204)

f=function(x) {
  m=matrix(" ",x,26)
  i=x
  d=ifelse(x==1,0,-1)
  for (j in 1:26) {
    m[i,j]=LETTERS[j]
    if (!((i+d) %in% 1:x)) d=-d
    i=i+d
  }
  for (i in 1:x) cat(m[i,],"\n",sep="")
}

Wynik

> f(1)
ABCDEFGHIJKLMNOPQRSTUVWXYZ
> f(2)
 B D F H J L N P R T V X Z
A C E G I K M O Q S U W Y 
> f(3)
  C   G   K   O   S   W   
 B D F H J L N P R T V X Z
A   E   I   M   Q   U   Y 
> f(7)
      G           S       
     F H         R T      
    E   I       Q   U     
   D     J     P     V    
  C       K   O       W   
 B         L N         X Z
A           M           Y 
djhurio
źródło
Widzę, co tu zrobiłeś! Bardzo sprytny ...
Kroltan
1
+1 Schludnie! Możesz jednak pozbyć się spacji wokół swoich foroświadczeń ( for(i in 1:x)cat(...na przykład) lub otaczających %in%.
plannapus
3

JavaScript - 248 224 235

z=~~prompt(),y="ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");y[9]="Javascript";for(w=[],v=0;v<z;v++)w[v]="\n";v--;for(i=0;i<26;i++){for(j=0;j<z;j++)w[j]+=j-v?i-9?" ":"          ":y[i];~~(i/(z-1))%2?v++:v--;}if(z==1)w=y;console.log(w.join(""))

Oto link do jsfiddle, gdzie możesz go przetestować.
edycja: Utworzono dziennik konsoli dla czcionki o stałej szerokości i usunięto przecinki, jeśli input == 1.

izlin
źródło
Sugestie: 1: parseInt i Math.floor można zmienić za pomocą operacji wymuszania liczb całkowitych, takich jak |0lub ~~. 2: krótsze jest budowanie tablicy w bezpośrednio, bez split. for(w=[],v=0;v<z;v++)w[v]="\n";
edc65
... i nie ma instrukcji wyjściowej (console.log lub cokolwiek, co użyjesz w skrzypcach, jest to część liczby
znaków
@ edc65 Dziękujemy za wskazówki. Miałeś rację. Zapomniałem danych wyjściowych, więc dodałem alert, ale nie ma czcionki mono-odstępowej, więc wygląda dość chaotycznie.
izlin
@izlin Zamiast (i==9?" ":" ")ciebie możesz użyć (i^9?" ":" "), który ratuje postać.
rev
1
WSPARCIE! czy ktoś może wyjaśnić? (Dlaczego jest dwa razy <code> v = 0 </code>?)
flawr
3

Perl 119

$s.=/26/?++$r&&$/:$m-1&&$r-abs$_%(2*$m-2)+1-$m?$"x(1+3*/15/):/15/?Perl:(A..Z)[$_]for(0..26)x($m=<>);print$s=~s/\s+$//rg

Ten program pobiera dane wejściowe STDINi drukuje wynik STDOUT.

I bonus - wersja niezgodna z regułami, ponieważ drukuje końcowe spacje, ale dodaje pewne interakcje:

#!/usr/bin/perl -p
$r=0;$_=join'',map{/26/?++$r&&$/:$m-1&&$r-abs$_%(2*$m-2)+1-$m?$"x(1+3*/15/):/15/?Perl:(A..Z)[$_]}(0..26)x($m=$_)

... i niektóre testy poniżej:

1
ABCDEFGHIJKLMNOPerlQRSTUVWXYZ
2
 B D F H J L N Perl R T V X Z
A C E G I K M O    Q S U W Y
4
   D     J     Perl     V
  C E   I K   O    Q   U W
 B   F H   L N      R T   X Z
A     G     M        S     Y
6
     F         Perl         Z
    E G       O    Q       Y
   D   H     N      R     X
  C     I   M        S   W
 B       J L          T V
A         K            U
rdzeń 1024
źródło
3

J, 67 57 61 znaków

echo@dtb"1@|.@|:@(26&,$(u:65+i.26)#~1 j.26$(0#~1=]),<:#-&0 2)

Użyj jako funkcji:

   echo@dtb"1@|.@|:@(26&,$(u:65+i.26)#~1 j.26$(0#~1=]),<:#-&0 2)
   D     J     P     V
  C E   I K   O Q   U W
 B   F H   L N   R T   X Z
A     G     M     S     Y

Objaśnienie: w tym rozwiązaniu zastosowano inne podejście niż w innym rozwiązaniu J. Zamiast generować falę piłokształtną 0 1 2 3 2 1 0 1 ... spojrzałem na odstępy między kolejnymi literami. Na przykład, dla n = 4, jeśli się od A do góry, owinąć w drugiej kolumnie i zasięgu B, to znajdują się cztery odstępy pomiędzy A i B. Ten wzór odstępy między literami jest bardzo regularne: dla n = 4 wzór to 4 4 4 2 2 2 4 4 4 ... .

Chodzi więc o to, aby najpierw zbudować spłaszczoną (i transponowaną) tablicę, a następnie przekształcić ją i odwrócić, aby wyglądała poprawnie. Procedura wyjściowa jest prosta (przynajmniej jako J): dtb to „usuń końcowe spacje” i "1mówi „operuj na każdej linii”. dtb i echo są dostarczane przez standardową bibliotekę.

Podziękowania dla Zsbána Ambrusa za pomoc w grze w golfa.

Robaczek świętojański
źródło
3

MetaPost (207)

numeric h,d,y;h=5;d=-1;y=1;u=5mm;pair p;string s;for x=1upto26:p:=(x,y)*u;s:=char(x+64);if x=13:s:="MetaPost";elseif x>13:p:=(x+2,y)*u;fi;label.rt(s,p);if(y=h)or(y=1):d:=d*-1;fi;if h=1:d:=0;fi;y:=y+d;endfor;

wprowadź opis zdjęcia tutaj

Możesz spróbować tutaj.

wada
źródło
2

Bash (213) (223)

read i
p=0
d=1
printf '\n%.0s' `seq $i`
for l in {A..Z}
do (($p==$i-1))&&((p=$p*-1))
(($i==1))&&p=0
(($p!=0))&&echo -en "\033[s\033[${p#-}A"
[[ "$l" == "B" ]]&&l="Bash"
echo -en $l"\033[s\033[${p#-}B"
((p++))
done

Drobne poprawki, a my spadamy do 213.

Pierwotny miał drobny błąd. Testowany i potwierdzony do pracy w wersji bash 4.2.37.

Dzięki @manatwork za wskazanie błędu i kilka wskazówek.

Ok
źródło
Zredagowałem twój post, dodając do niego podświetlanie składni, ale teraz widzę, że źle podświetlił część twojego kodu jako komentarz, więc wycofałem go. Powiedziałem to na wypadek, gdybyś zastanawiał się, dlaczego wycofałem go :)
ProgramFOX
@ProgramFOX W porządku. W każdym razie dzięki!
Okw
Myślę, że gdzieś jest niewielki błąd, ponieważ wyjście powoli spada. (Przynajmniej w wersji Bash 4.3.) Kilka drobnych usprawnień w celu zmniejszenia rozmiaru do 194 znaków: pomiń pieczęć w obliczeniach arytmetycznych, nie próbuj podwójnie cytować w cudzysłowie: pastebin.com/zKa3zdwR
manatwork
Czy możesz użyć nowego wiersza zamiast niektórych, ;aby uczynić go nieco bardziej czytelnym? Nie wpłynie to na twój wynik golfowy
Digital Trauma
2

Haskell - 432 bajtów (niestety ...)

Okazało się to o wiele trudniejsze, niż się spodziewałem, aby osiągnąć czysto, stąd też liczba dużych bajtów. Jestem pewien, że mógłbym (lub ktoś) poradzić sobie lepiej, ale spędziłem na tym zbyt wiele czasu. Wersja do gry w golfa jest następująca:

import Data.Matrix
import Data.Vector(toList)
r=repeat
s h=y h$l(take 26(case h of 1->r 1;_->concat$r$[h,h-1..1]++[2..h-1]))['A'..'Z']$matrix h 32(const ' ')<|>matrix h 1(const '\n')
l _[]m=m
l(x:i)(r:e)m=l i e$u m(let z=26-length i in if z<9 then z else z+6)x r
l _ _ m=m
u m c r h=case h of 'H'->t c r"Haskell"m;_->setElem h(r,c)m
t _ _[]m=m
t c r(x:i)m=t(c+1)r i$setElem x(r,c)m
y h m=concat[toList$getRow x m|x<-[1..h]]

Aby uruchomić, załaduj kod ghcii wykonaj, putStr $ s Intgdzie Intjest pożądana wysokość. Możesz także dodać

import System.Environment
main :: IO ()
main = fmap (s . read . head) getArgs >>= putStr

pod imports w pliku tekstowym, skompiluj go ghci podaj wysokość jako argument wiersza poleceń. Wersja bez golfa:

import System.Environment
import Data.Matrix
import Data.Vector (toList)

main :: IO ()
main = fmap (sawtooth . read . head) getArgs >>= putStr

type M = Matrix Char

sawtooth :: Int -> String
sawtooth height = let mat     = matrix height 32 (const ' ') <|> matrix height 1 (const '\n')
                      numbers = take 26 (case height of 1 -> repeat 1
                                                        _ -> concat $ repeat $ [height,height-1..1]++[2..height-1])
                      chars   = ['A'..'Z']
                  in toString height $ makeMatrix numbers chars mat

makeMatrix :: [Int] -> String -> M -> M
makeMatrix []     []     mat = mat
makeMatrix (x:xs) (s:ss) mat = makeMatrix xs ss $ updateMatrix
                                                    mat (let z = 26 - length xs in if z < 9 then z else z + 6) x s
makeMatrix _      _      mat = mat

updateMatrix :: M -> Int -> Int -> Char -> M
updateMatrix mat col row char = case char of 'H' -> insertHaskell col row "Haskell" mat
                                             _   -> setElem char (row, col) mat

insertHaskell :: Int -> Int -> String -> M -> M
insertHaskell _   _   []     mat = mat
insertHaskell col row (x:xs) mat = insertHaskell (col+1) row xs $ setElem x (row, col) mat

toString ::Int -> M -> String
toString height mat = concat [ toList $ getRow x mat | x <- [1..height] ]
DrJPepper
źródło
Wierzę, że można zastąpić constz pure(za pomocą aplikacyjnych instancji do funkcji), aby zaoszczędzić kilka bajtów.
Esolanging Fruit
2

C # / LINQ:

using System;
using System.Linq;

namespace SawtoothAlphabet
{
    class Program
    {
        static void Main(string[] args)
        {
            int N = Int32.Parse(args[0]);   // eg 4
            Console.WriteLine(
                String.Join(Environment.NewLine, Enumerable.Range(0, N).Select(line =>
                    String.Concat(Enumerable.Range(0, 26).Select(i =>
                        line == Math.Abs(i % (2 * (N - 1)) - (N - 1))
                            ? (i == 2) ? "C#" : Char.ConvertFromUtf32(i + 'A')
                            : (i == 2) ? "  " : " ")
            ).TrimEnd())));
        }
    }
}

Krótkie wyjaśnienie: Enumerable.Range(0, N).Select(...)powoduje generowanie ciągu dla każdej linii, która ostatecznie jest łączona w pojedynczy ciąg z String.Join(Environment.NewLine, ...). Dla każdego wiersza, w którym przewijamy wszystkie 26 znaków Enumerable.Range(0, 26).Select(...), test na początku wyrażenia lambda określa, czy wygenerować znak, czy spację, podczas gdy i==2sprawdza „C” i konwertuje go na „C #” lub na dwie spacje w zależności od linii . W String.Concat(...)przekształca otrzymany IEnumerable<char>dla każdej linii w ciągu przed przekazaniem go TrimEnd(...)do czysto znieść każdej spacji spływu.

Mark Feldman
źródło
1

PHP (216) (205)

Nowa wersja:

$b=array_fill(65,26,' ');$b[80]='   ';$b=array_fill(0,$i,$b);for($j=--$i,$x=64;++$x<91;$i||$j=0){$b[$j][$x]=chr($x);$x==80&&$b[$j][$x]='PHP';$j+=($d=$j<($d?$i:1))*2-1;}echo join("\n",array_map('join',$b));

Stara wersja:

$b=array_fill(0,$i,array_fill(0,28,' '));for($j=--$i,$x=-1;++$x<28;$i||$j=0){$q=&$b[$j];$q[$x]=chr($x-($x&16)/8+65);$x==15&&($q[++$x]='H')*$q[++$x]='P';$j+=($d=$j<($d?$i:1))*2-1;}echo join("\n",array_map('join',$b));

oczekuje, że zmienna $ i będzie wysokością.

Christoph
źródło
1

C, 214 169 bajtów, bez spacji końcowych

Dziękuję @ edc65 i @tolos za ich pomocne sugestie.

#define C ((c-i+n-65)%z&&(c+i+n-67)%z)
n,i,m,c,z;main(){scanf("%d",&n);z=n<2?1:2*n-2;for(;i++<n;){for(m=c=64;c++<90;)m=C?m:c;for(c=64;c++<m;)putchar(C?32:c);puts("");}}
Ziemia
źródło
3
To przegrana bitwa, ale upieram się: #include <stdio.h> nie jest potrzebny w wielu przypadkach, czy to gcc, czy inny kompilator. W każdym razie jest to standardowe i poprawne C.
edc65
2
@ edc65: Zależy od tego, co uważasz za „prawidłowy C”. Jest to poprawny K&R C AFAIK, ale ANSI / ISO C wymaga, aby funkcje variadic (które obejmują scanfi printf) otrzymywały prototypy, w przeciwnym razie otrzymasz niezdefiniowane zachowanie. #include <stdio.h>jest oczywiście najkrótszym sposobem na przekazanie prototypu zarówno do, jak scanfi do printf.
celtschk
@celtschk ważny K&R wystarcza mi w golfie kodowym. A „w wielu przypadkach” (gdy na przykład używa się tylko putów) jest poprawne C89. Chcę podkreślić, że nie jest to dziwne zachowanie gcc. (W każdym razie prosi o notatkę o funkcjach variadic)
edc65
1
Globale są typu int i inicjowane na zero. Równie dobrze może zrzucić intdeklarację dla głównego, jeśli nic nie zwracasz. Może spaść dodatkowych nawiasów, wymienić ' 'z 32oraz if(!C)m=cz oświadczeniem ternarny, a jak tylko dowiedział (powyżej) zastąpić printf("\n")z puts("")do 18 znaków:n,i,m,c,z;main(){;scanf("%d",&n);z=n<2?1:2*n-2;for(;i<n;i++){for(m=c=65;c<91;c++)m=C?m:c;for(c=65;c<=m;c++)printf("%c",C?32:c);puts("");}}
1

JavaScript ( 204 185 150)

h=m=4;d=h>1?-1:0;o=[];for(a=0;a<35;a++){for(r=h;r;r--)o[r]=(o[r]||"")+(r==m?"ABCDEFGHIJavascriptKLMNOPQRSTUVWXYZ"[a]:" ");if(a<9||a>17){m+=d;if(m<2||m==h)d=-d}}console.log(o.join("\n"))

EDYTOWAĆ

Zapisano 13 bajtów, nie budując tablicy i .join („\ n”). Wymagane przerzucanie pętli for. Następnie, z pomocą syna kodującego C, kod był zbyt sprytny, aby zapisać kolejne 12 bajtów.

Oto czytelna wersja pokazująca zmianę logiki.

for (row = height; row; row--) {
    rowOfNextActiveLetter = 1;
    direction = height > 1 ? -1 : 0;
    output = "";
    for (a = 0; a < 35; a++) {
        output += (row == rowOfNextActiveLetter ? "ABCDEFGHIJavascriptKLMNOPQRSTUVWXYZ"[a] : "");
        if (a < 9 || a > 17) {
            rowOfNextActiveLetter -= direction;
            if (rowOfNextActiveLetter < 2 || rowOfNextActiveLetter == height)direction = -direction
        }
    }
    console.log(output)
}

Gra w golfa (161):

for(r=h;r;r--){m=1;d=h>1?-1:0;o="";for(a=0;a<35;a++){o+=(r==m?"ABCDEFGHIJavascriptKLMNOPQRSTUVWXYZ"[a]:" ");if(a<9||a>17){m-=d;if(m<2||m==h)d=-d}}console.log(o)}

Gra w golfa i zaciemniony (149):

for(r=h;r;r--,console.log(o))for(m=1,d=h>1?1:0,o="",a=0;a<35;)if(o+=r==m?"ABCDEFGHIJavascriptKLMNOPQRSTUVWXYZ"[a]:" ",a<9|a++>17)d=(m+=d)<2|m==h?-d:d
John Nowlin
źródło
Lubię to, nawet jeśli nie rozumiem tego w pełni. Ale w każdym razie możesz wyciąć 9 znaków usuwając substr i używając bezpośredniego indeksu .substr(a,1)=>[a]
edc65
Możesz go jeszcze bardziej zawęzić, używając operatorów bitowych i iteratorów koalescencyjnych dla 182: h=m=4;d=1<h?-1:0;o=[];for(a=0;35>a;a++){for(r=h;r;r--)o[r]=(o[r]||"")+(r==m?"ABCDEFGHIJavascriptKLMNOPQRSTUVWXYZ"[a]:" ");if(9>a|17<a)if(m+=d,2>m||m==h)d=-d}console.log(o.join("\n"))
WallyWest,
ups, posprzątałem o jeden zbyt wiele miejsc
John Nowlin
1

K, 60 bajtów

`0:'{+{x!y}.'+(26#{(!x),|1_!x-1}x;(((x-1)#" "),)'`c$65+!26)}

Całkiem proste i wygląda na to, że właśnie usunąłem rozwiązanie J. :)

Najpierw wygeneruj alfabet:

  `c$65+!26
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"

I fala piłokształtna o odpowiedniej długości:

  26#{(!x),|1_!x-1}5
0 1 2 3 4 3 2 1 0 1 2 3 4 3 2 1 0 1 2 3 4 3 2 1 0 1

Wypełnij każdą literę alfabetu wiodącymi spacjami:

  (((5-1)#" "),)'"ABC"
("    A"
 "    B"
 "    C")

Zapnij alfabet i kwadratową falę razem i obróć każdy wiersz:

  +(0 1 2;("  A";"  B";"  C"))
((0
  "  A")
 (1
  "  B")
 (2
  "  C"))

  {x!y}.'+(0 1 2;("  A";"  B";"  C"))
("  A"
 " B "
 "C  ")

A transpozycja tego jest naszą odpowiedzią:

  +{x!y}.'+(0 1 2;("  A";"  B";"  C"))
("  C"
 " B "
 "A  ")

Wypróbuj tutaj w OK .

JohnE
źródło
0

C: 142 139 znaków

Okropnie długo, spodziewam się, że będę mógł go trochę skrócić:

char a[26][27],i,j,p,d;main(n){for(scanf("%d",&n);i<26;d^=!p^p+2>n,p+=d-(d^n>1),i++)for(j=n;j--;a[j][i]=p^j?32:i+65);while(n)puts(a[--n]);}

Nieco bardziej czytelny:

char a[26][27], i, j, p, d;
main(n) {
    for (
        scanf("%d", &n);
        i < 26;
        d ^= !p ^ p + 2 > n,
        p += d - (d ^ n > 1),
        i++
    )
        for (
            j = n;
            j--;
            a[j][i] = p ^ j
                ? 32
                : i + 65
        );

    while (n)
        puts(a[--n]);
}

Edycja: Brakowało mi reguły „brak spacji końcowych”, ale wrócę.

Fors
źródło
0

Scala, 246 bajtów

def f(h:Int)={val a=Seq.fill(h)(Array.fill(32)(' '));var(r,x,d)=(h-1,0,if(h==1)0 else-1);def p(c:Char){a(r)(x)=c;x+=1};for(c<-'A'to'Z'){p(c);if(c==83)"cala"foreach p;r+=d;if(r==0|r==h-1)d*= -1};for(z<-a)println(new String(z)replaceAll(" +$",""))}

sformatowany i skomentował:

def f(h: Int) = {
  val a = Seq.fill(h)(Array.fill(32)(' '));
  // r - row; x - x coordinate, column; d - direction
  var (r, x, d) = (h - 1, 0, if(h==1) 0 else -1); 
  def p(c: Char) { // p for "put the character"
    a(r)(x) = c;
    x += 1
  };
  for(c <- 'A' to 'Z') { 
    p(c);
    if(c == 83)      // 83 == 'S'
      "cala" foreach p;
    r += d;
    if(r == 0 | r == h - 1)     // | is shorter than || 
      d *= -1
  };
  for(z <- a)
    println(new String(z) replaceAll (" +$", ""))  // trimming trailing whitespace
}

Wyniki:

scala> f(4)
   D     J     P         V
  C E   I K   O Q       U W
 B   F H   L N   R     T   X Z
A     G     M     Scala     Y

scala> f(5)
    E       M           U
   D F     L N         T V
  C   G   K   O   Scala   W
 B     H J     P R         X Z
A       I       Q           Y

scala> f(1)
ABCDEFGHIJKLMNOPQRScalaTUVWXYZ
Karol S.
źródło
0

Python - 137

Dane do zapisania w Iieg i=8

l=[""]*h;k=j=0;y=h-1;exec'l[y]+=" "*(j-len(l[y]))+chr(k+65)+"ython"*(k==15);j=len(l[y]);y-=1^k/(h-(h>2))%2*-2;k+=1;'*26;print"\n".join(l)
Vectorized
źródło
0

Rakieta

Oto czysta funkcjonalna wersja: sugestie, aby ją skrócić witamy.

(define (sawtooth n)
  (define (ST i d m lns)
    (if (null? m) 
        lns
        (let* ([v (first m)]
               [spc (make-string (string-length v) #\space)]
               [I (+ i d)])
          (ST I
              (if (or (zero? I) (= (sub1 n) I)) (* d -1) d)
              (rest m)
              (for/list ([ln lns] [j n])
                       (~a ln (if (= i j) v spc)))))))
  (displayln
   (string-join 
    (ST (sub1 n)
        (if (= n 1) 0 -1) 
        (string-split "A B C D E F G H I J K L M N O P Q Racket S T U V W X Y Z")
        (make-list n "\n")))))

Wynik

> (sawtooth 1)
ABCDEFGHIJKLMNOPQRacketSTUVWXYZ

> (sawtooth 2)
 B D F H J L N P Racket T V X Z 
A C E G I K M O Q      S U W Y 

> (sawtooth 8)
       H                  V     
      G I                U W    
     F   J              T   X   
    E     K            S     Y  
   D       L     Racket       Z 
  C         M   Q               
 B           N P                
A             O  
użytkownik29983
źródło