Wygeneruj trójkąt prostokątny


10

W tym wyzwaniu musisz wziąć dwie liczby (oddzielone spacją) jako dane wejściowe i wyjściowe prostokąta ASCII, złożonego z xs.

Pierwsza liczba będzie szerokością i wysokością trójkąta, który powinieneś wyprowadzić. Drugi numer będzie tym, w którym rogu będzie kąt prosty. Rogi są ponumerowane od 1 do 4, zaczynając od lewego górnego rogu i idąc w kolejności czytania w języku angielskim:

1    2



3    4

Na przykład (dane wejściowe i odpowiadające im wyjścia trójkątne):

INPUT | 3 1 | 3 2 | 3 3 | 3 4
------+-----+-----+-----+----
 OUT- | xxx | xxx | x   |   x
 PUT  | xx  |  xx | xx  |  xx
      | x   |   x | xxx | xxx

Dane wyjściowe programu muszą dokładnie odpowiadać tym przykładom dla odpowiednich danych wejściowych.

Dane wejściowe zawsze będą ważne: pierwsza liczba będzie liczbą całkowitą ≥1, a druga liczba będzie wynosić 1, 2, 3 lub 4.

To jest ; najkrótszy kod (pod względem liczby znaków) wygrywa.

Odpowiedzi:


9

APL (30)

{' x'[1+(⍎⍵⌷'⌽+⍉⊖')≤/¨⍳2⍴⍺]}/⎕

Wyjaśnienie:

  • {... }/⎕: redukuj daną funkcję nad wejściem (więc jeśli wejście ma 2 liczby, wywołuje funkcję z tymi dwiema liczbami, będąc lewą i prawą liczbą)
  • ≤/¨⍳2⍴⍺: Należy się -by- macierz współrzędnych i ustawić te pozycje, w których współrzędna X nie jest większa niż współrzędna Y daje bitowym.
  • (⍎⍵⌷'⌽+⍉⊖'): wybierz funkcję transformacji podaną przez, aby umieścić trójkąt prawą stroną do góry.
  • ' x'[1+... ]: dodaj jeden do pola bitowego i użyj wyniku jako indeksu w ciągu ' x', wstawiając miejsce na 0 i xna 1.

1
Im więcej APL czytam, tym bardziej zdaję sobie sprawę, że APL to parsujący koszmar. Czy nie musiałby faktycznie ocenić (⍎⍵⌷'functions')części, zanim zdecyduje, jak interpretować całe stwierdzenie? Rozważ na przykład 1+(⍵⌷'12+')|40. Nie wiedziałby nawet, czy |jest monadyczny czy dyadyczny przed wejściem w tę nawiasową część. Całe abstrakcyjne drzewo składniowe zmienia się w zależności od oceny.
Protist

Miałem na myśli 1+(⍎⍵⌷'12+')|40... nie pozwolę mi edytować.
Protist

2
@protist: Ciekawostka: f ← { [ }nie daje błędu! f 1÷0daje ... błąd domeny ! (z powodu podziału przez zero). Tylko wtedy, gdy wywołasz funkcję tak, f 123jakbyś miał błąd składniowy . Oto: imgur.com/jtmdi4B
marinus

Na wszystkich bogów !!!! To trochę łamie mi serce. Bawiłem się pisaniem niektórych tłumaczy APL, co pokazuje wielkie zło w obecnych implementacjach. hahaha
protist

Wygląda na to, że funkcje są wprowadzane rutynowo przez jakiś brzydki proces przypominający makropolecenie. Oznaczałoby to nieco rozwinięcie tekstu w miejscu.
Protist

6

Ruby, 116 115 109 96

Zacznę od własnego rozwiązania.

i=gets.split
s=i[0].to_i
(i[1]<?3?s.downto(1):1..s).map{|x|t=?x*x
puts /2|4/=~i[1]?t.rjust(s):t}

Wiem tylko, że prawie natychmiast pokonają mnie 30-znakowe rozwiązanie GolfScript: P

Dzięki Minitech za golenie 19 znaków (wow)!


Zamiast tego ==0możesz użyć <1. ?x*xratuje inną postać. Ponadto, puts i[1]%2<1?t.rjust(s):t}by rade, prawda?
Ry-

Hmm… masz wokół przestrzeni ?? Czy to konieczne? Myślę też, że możesz zrobić to samo z r=.
Ry-

@minitech Jest to konieczne - spacja wiodąca, ponieważ w przeciwnym razie jest analizowany 1?jako pojedynczy token, a spacja końcowa, ponieważ w przeciwnym razie jest analizowany jako ?t(co jest równoważne 't'). Jak proponujesz restrukturyzację rczęści?
Klamka

Próbowałeś? W jakiej wersji Ruby? Działa dobrze dla mnie w wersji 2.0.
Ry-

@minitech Dziwne, wcześniej nie działało, a teraz działa: P Dzięki
Klamka

4

GolfScript ( 34 33 znaków)

~\:^,{)' x'^*$>^<0(2$?%}%\(2&(%n*

Szkoda, że ​​narożniki nie są ponumerowane obrotowo, ponieważ pozwoliłoby to na bardziej eleganckie podejście do budowania jednej tablicy, a następnie obracania jej nrazy:

~\:^,{)' x'^*$>^<}%{-1%zip}@)*n*

3

C # - 195

using System;class P{static void Main(string[]a){int G=int.Parse(
a[0]),O=int.Parse(a[1]),L=O<3?0:G+1,F=O<3?-G:1;G=O%2>0?-G:G;for(;
F<L;F++)Console.Write("{0,"+G+"}\n","".PadRight(F<0?-F:F,'x'));}}

Sformatowany:

using System;
class P
{
    static void Main(string[] a)
    {
        int G = int.Parse(a[0]),
            O = int.Parse(a[1]),
            L = O < 3 ? 0 : G + 1,
            F = O < 3 ? -G : 1;

        G = O % 2 > 0 ? -G : G;

        for(; F < L; F++)
            Console.Write("{0," + G + "}\n", "".PadRight(F < 0 ? -F : F, 'x'));
    }
}

wprowadź opis zdjęcia tutaj


Dane wejściowe muszą być rozdzielane spacjami, a nie przecinkami.
Klamka

@Doorknob: Zrzut ekranu pochodzi z programu testowego, w którym postanowiłem pokazać dane wejściowe przecinkiem. Dane wejściowe są w rzeczywistości rozdzielane spacjami podczas uruchamiania programu, chociaż jest to kwestia sporna, ponieważ wszystkie aplikacje konsoli C # otrzymują dane wejściowe jako tablicę ciągów.
Igby Largeman,

2

Skrypt golfowy, 39 36 35 znaków

~\:y,{' '*'x'y*+y<0~2$?%}%-1@2>?%n*

demo na żywo: http://golfscript.apphb.com/?c=OyczIDInCn5cOnkseycgJyoneCd5Kit5PC0xIDIkPyV9JS0xQDI%2BPyVuKgo%3D

szkoda, że ​​nie ma 30 znaków zgodnie z życzeniem


Wymiana 1${-1%}*z -1 2$?%i \2>{-1%}*z \2>-1\?%złowi Ci 2 znaki.
Zmienność

@ Dzięki zmienności, włączone
John Dvorak

@ Lotność -1 2można napisać0~2
Howard

A dla kolejnego chara musimy jeszcze trochę zrestrukturyzować:~(\:y,{{>'x '=}+y,%0~2$?%}%\2&(%n*
Howard,

2

Mathematica 122 (104?)

g@s_ := ({w, p} = ToExpression@StringSplit@s; 
   Array[If[Switch[p, 1, # <= (w + 1 - #2), 2, # <= #2, 3, # >= #2, 4, # > (w - #2)],
   "X", ""] &, {w, w}]) // Grid

GraphicsGrid[{{g["12 1"], g["12 3"]}}]

inna metoda


Zgodnie z liberalną interpretacją „wyjścia”, następujące (104 znaki) będą działać.

f@s_ := ({w, p} = ToExpression@StringSplit@s; 
  Graphics[Polygon@Delete[{{w, 0}, {0, 0}, {w, w}, {0, w}}, p], Axes -> True])


f["50 4"]

trójkąt


Jeśli wprowadzanie danych w formie listy jest dozwolone, wystarczy (75 znaków):

f[{w_, p_}] := 
 Graphics[Polygon@Delete[{{w, 0}, {0, 0}, {w, w}, {0, w}}, p], Axes -> True]


Technicznie jest to niezgodne z zasadami: P
Klamka

Jaką zasadę to narusza?
DavidC

Tabelę wejścia / wyjścia, którą umieściłem. 122-char jeden jest jednak dobry. Zredagowałem pytanie, aby wyjaśnić
Klamka

Ups Myślałem, że wykres jest po prostu przykładem.
DavidC

Właśnie umieściłem wersję artystyczną ASCII na pierwszym miejscu.
DavidC

2

J, 59 55 42 38 37 36 znaków

Jeśli dozwolone jest wprowadzanie danych na końcu programu:

(|:@|.@]^:([:|[+_7*2<[)[:[\'x'$~])~/

Jeśli nie (dodatkowe 3 znaki):

t=.(|:@|.@]^:([:|[+_7*2<[)[:[\'x'$~])~/

Stosowanie:

   (|:@|.@]^:([:|[+_7*2<[)[:[\'x'$~])~/3 4
  x
 xx
xxx

lub

   t 3 4
  x
 xx
xxx

Myślę, że może to być nieco krótsze, ponieważ większość znaków to nawiasy kwadratowe i wielkie litery, aby zachować ukryty styl.

Edytuj
Używając gerunda, a czasownik programu odciął kilka znaków, ale wciąż jest tam zbyt wiele wielkich liter dla moich upodobań.

Edycja 2
To trochę bardziej. Zrzucenie porządku dziennego, aby uzyskać listę wymaganych obrotów, pozwala pozbyć się większości dodatkowych nawiasów i kilku wielkich liter.

Edycja 3
Pozbyłem się w tym czasie ostatniej obcej czapki i pary wsporników. Musisz znaleźć tańszy sposób kodowania wymaganej liczby obrotów.

Edycja 4 Użyj prefiksu zamiast sufiksu, aby odciąć znak. Umożliwia inny sposób tworzenia listy, który nie zapisuje żadnych znaków. Facet.

Edytuj 5
Używając formuły, aby odciąć inną postać. Nadal uważam, że ten kawałek może być krótszy.


1

Python 106 znaków

w,d=map(int,raw_input().split())
for e in range(1,w+1)[::d/3*2-1]:print('%'+'-+'[d%2]+str(w)+'s')%('*'*e)

1

Python 3, 91

Na podstawie odpowiedzi Abhijita.

Zmodyfikowano tworzenie ciągu wyjściowego, aby uniknąć sumy ciągów i brzydkich 1s w range. Python 3 pozbywa się raw_w raw_input, ale sprawia, że należy użyć //do całkowitej Division, aby dodać do nawiasów print, dzięki czemu oszczędza tylko jeden znak.

w,d=map(int,input().split())
for e in range(w)[::d//3*2-1]:print('%*s'%(w-d%2*2*w,'x'*-~e))

0

Kociak , 140

def s{><replicate}
getLine{' 'neChar}span{readInt fromSome}toBoth->{w n}
w 0 if(n 2>){><}..
{<>w>< -{'X's}{' 's}both if(n 2%0=){><}cat say}each

Nie golfowany:

getLine
{' ' neChar} span
{readInt fromSome} toBoth
->{ width corner }

width 0
if (corner 2 >):
  swap
..

{ ->index
  'X' index replicate
  ' ' (width index -) replicate
  if (corner 2 % 0 =):
    swap
  cat say
} each

Dowód, że muszę wdrożyć przeciążenie i rozwinąć standardową bibliotekę.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.