Znaczące białe znaki


55

Definiujemy białe znaki jako dowolny z trzech znaków, tabulacji (0x09), nowej linii (0x0A) lub spacji (0x20).

W tym wyzwaniu musisz napisać dwa programy lub funkcje w tym samym języku programowania, które wykonują następujące zadania:

  1. Policz znaki białych znaków w danym ciągu. Na przykład dane wejściowe

      123 -_-   abc
    def
    

    zwróci 7 (pod warunkiem, że nie ma końcowego nowego wiersza).

  2. Podziel dany ciąg przy kolejnych biegach białych znaków. Jeśli ciąg zaczyna się lub kończy spacją, na końcu nie należy zwracać pustych ciągów. Na przykład to samo wejście

      123 -_-   abc
    def
    

    wróciłby ["123", "-_-", "abc", "def"].

W obu przypadkach możesz pobrać dane wejściowe za pośrednictwem STDIN, argumentu wiersza poleceń lub argumentu funkcji i zwrócić wynik lub wydrukować go STDOUT. W przypadku drugiego programu, jeśli zdecydujesz się na drukowanie do STDOUT, wydrukuj każdy ciąg w osobnym wierszu, bez otaczających go cudzysłowów.

W przypadku obu programów można założyć, że dane wejściowe zawierają tylko drukowalne ASCII (0x20 do 0x7E) i białe znaki.

Teraz jest haczyk:

  • Jeśli wszystkie białe znaki zostaną usunięte z obu programów / funkcji, powstałe ciągi muszą być identyczne. Oznacza to, że Twoje dwa zgłoszenia mogą różnić się jedynie liczbą i rozmieszczeniem białych znaków.
  • Żaden program / funkcja nie może zawierać literałów łańcuchowych ani wyrażeń regularnych (literały znakowe są w porządku, pod warunkiem, że Twój język ma określony typ znaków).
  • Żaden program / funkcja nie może zawierać żadnych komentarzy.
  • Nie wolno czytać kodu źródłowego programu, bezpośrednio lub pośrednio.

To jest kod golfowy. Twój wynik to suma rozmiarów obu rozwiązań (w bajtach). Najniższy wynik wygrywa.

Liderów

Poniższy fragment kodu generuje zarówno zwykłą tabelę wyników, jak i przegląd zwycięzców według języka. Więc nawet jeśli wybrany język nie pozwala ci wygrać całego wyzwania, dlaczego nie spróbować zająć miejsca na drugiej liście? Byłbym bardzo zainteresowany, aby zobaczyć, jak ludzie radzą sobie z tym wyzwaniem w różnych językach!

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

# Language Name, N bytes

gdzie Njest całkowity rozmiar Twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Możesz także uwzględnić indywidualne liczby przed całkowitą liczbą, np

# Python 2, 35 + 41 = 76 bytes

Ostatni numer, który nie zostanie przekreślony, zostanie użyty przez fragment kodu.

<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>site = 'meta.codegolf',postID = 5314,isAnswer = true,QUESTION_ID = 42253;jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)<\\/code><\/pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>


26
Ta tabela liderów jest fajna!
Digital Trauma

5
Wygląda na to, że jakakolwiek odpowiedź na
Białą Przestrzeń

1
@ nyuszika7h Rzeczywiście tak, ale i tak nie będzie szczególnie krótki.
Martin Ender,

7
Znacząca
biała

Odpowiedzi:


15

Pyth, 16 + 15 = 31 bajtów

Wypróbuj tutaj .

Licznik:

L@,cb)sm!cd)b1 0

Rozłupnik:

L@,cb)sm!cd)b10

Każdy z nich definiuje funkcję, yktóra pobiera ciąg znaków w celu rozwiązania żądanego zadania.

Podziękowania dla @FryAmTheEggman za pomysł wykorzystania funkcji Pytha modułowego indeksowania list do golenia postaci.

Przypadki testowe:

L@,cb)sm!cd)b1 0y++"abc def"b"gh ij k"
L@,cb)sm!cd)b10y++"abc def"b"gh ij k"

Wyjaśnienie:

L                  define a function, y, which takes one input, b.
 @                 Index into
  ,                2-tuple of
   cb)             b.split()                          (solution to splitter)
   s               sum over                           (solution to counter)
    m              map, with input d, to
     !cd)          logical negation of d.split()      (empty list is falsy)
     b             over b.
                   Index is either:
   10
   1
                   Indexing is modulo the length of the list in Pyth.
 0                 In one case, a 0 with a leading space is outside the function.
                   Leading space suppresses print, so the 0 is invisible.

52

Python, 54 + 56 = 110 bajtów

Licznik:

m=lambda x:sum(y.isspace()for y in x)
+1
0<9or x.split()

Rozłupnik:

m=lambda x:sum(y.isspace()for y in x)+10<9or x.split()

W przypadku licznika korzystamy z faktu, że Python jest w porządku, mając tylko wyrażenie na linii. Konieczne jest podzielenie +1i 0<9or x.split()powstrzymanie NameErrorprzed wyrzuceniem a, ponieważ 0<9bycie Trueuniemożliwia x.split()ocenę z powodu zwarcia.

W przypadku rozdzielacza, ponieważ liczba białych znaków jest zawsze nieujemna, sum(y.isspace()for y in x)+10<9jest zawsze Falsei funkcja dzielenia ma zastosowanie.


Alternatywnie 1, 59 + 60 = 119 bajtów

Licznik:

m=lambda x:[x.split(),sum(y.isspace()for y in x)][min([1])]

Rozłupnik:

m=lambda x:[x.split(),sum(y.isspace()for y in x)][m in([1])]

Wyniki zarówno liczenia, jak i dzielenia są przechowywane na liście dwuelementowej. Lista jest indeksowana przez albo min([1]), zwracając minimum jednoelementowej listy zawierającej 1, lub m in([1]), która zwraca False(równoważne 0), co mnie jest zawarte w [1].


Alternatywnie 2, 67 + 69 = 136 bajtów

Licznik:

ted=1;s=lambda x:[x.split(),sum(y.isspace()for y in x)][not s or ted]

Rozłupnik:

ted=1;s=lambda x:[x.split(),sum(y.isspace()for y in x)][not sorted]

Podobnie jak powyżej, wyniki zarówno liczenia, jak i podziału są przechowywane na liście dwuelementowej. sortedjest wbudowaną funkcją, która jest prawdziwą wartością, więc not sortedzwraca False(równoważne 0). Ponieważ not s or ted, ponieważ sjest funkcją, a także prawdą, not sjest Falsei ted = 1jest zwracana.


Alternatywnie 3, 59 + 60 = 119 bajtów

Licznik:

def f(s):a=s.split();a1=len(s)-len((s*0).join(a));return a1

Rozłupnik:

def f(s):a=s.split();a1=len(s)-len((s*0).join(a));return a
1

Jest to funkcja, w której wynik rozdzielacza jest przechowywany w zmiennej a, a wynik licznika jest przechowywany w zmiennej a1. Tak jak poprzednio, w tym przypadku Python ma tylko wyrażenie w wierszu 1. Podział a1określa, co należy zwrócić z funkcji.


22
Znowu dałbym +1 za not sorted.
Martin Ender,

Jest znak nowej linii pomiędzy +1i 0<9or x.split()potrzebne?
isaacg

1
@isaacg Jeśli zależy Ci na wyjątkach, to tak
Sp3000

Możesz ogolić 3 bajty za pomocą m=lambda x:sum(y.isspace()for y in x)+00and x.split()i m=lambda x:sum(y.isspace()for y in x)+0;0and x.split()(co czyni ten średnik nową linią oczywiście)
cjfaure

@cjfaure Nie sądzę, że pierwszy działa jako rozdzielacz, jeśli nie ma białych znaków
Sp3000,

16

Java 8, 239 + 240 = 479

Policz białe znaki (zwraca liczbę całkowitą)

Object f(String s){String r=new String(new char[]{92,'s'}),e=new String();int intx=0;intx=1;return intx>0?s.chars().filter(c->c==9|c==10|c==32).count():java.util.Arrays.stream(s.split(r)).map(t->t.replaceAll(r,e)).filter(t->t.length()>0);}

Podziel w spacji (zwraca Stream <String>)

Object f(String s){String r=new String(new char[]{92,'s'}),e=new String();int intx=0;int x=1;return intx>0?s.chars().filter(c->c==9|c==10|c==32).count():java.util.Arrays.stream(s.split(r)).map(t->t.replaceAll(r,e)).filter(t->t.length()>0);}

Wyjaśnienie:

Object f(String s){
    String r=new String(new char[]{92,'s'}),e=new String();  // init regex'es

    int intx=0;     // critical variable

    intx=1;         // change intx to 1
              OR
    int x=1;        // new, unused variable

    return intx>0 ? // test variable to decide what to do
      s.chars().filter(c->c==9|c==10|c==32).count() :
      java.util.Arrays.stream(s.split(r)).map(t->t.replaceAll(r,e)).filter(t->t.length()>0);
}

Dla mnie wygląda to świetnie. +1
Rodolfo Dias,

Całkiem dobrze, biorąc pod uwagę, że Java musi być najgorszym językiem do gry w golfa.
tbodt

13

Biała spacja, 75 + 153 = 228

Odstępy, tabulatory i znaki nowej linii zostały zastąpione odpowiednio przez STL i złożone dla zapewnienia czytelności. Konwertuj na właściwy plik białych znaków za pomocą tr -d \\n | sed 'y/STL/ \t\n/'.

Licznik

SSSLLSSLSSSTSSSSSLSLSSLSTLTSTTTSLSLTSSLTSSTLTTLSSSTLTSSSLSLLLSSSLS
LLSLLTLST

Rozłupnik

SSSTLSSSLTTSLSSTLSSSLSLSTLTSTTTSLSSLSLTSLSSSTSSSSTLTSSTLTTTTLSSSTL
SLSTTSLSLSLLSSTTLSSSTSTSLSSSTLTTTLTSTSLTLSSSSSTLSSSLTTSLSSTSLLSLTL
LSSSLTLSSLSLTLLSSLLLL

2
Zastanawiałem się, ile to zajmie ...;)
Martin Ender,

4
Dzięki spacji stają się to dwa osobne wyzwania związane z golfem.
tbodt

13

Cudowny, 103 + 92 = 195

Licznik:

@0      @200@1@3
]]&1]]3W
  \\!!?001
        &0  >W@1
>W    @2/\  /\@3+A
00&0      &1
          Dp
@0//

Rozłupnik:

@0  @200@1    @3
]]&1]]  3W    \\
  !!    ?001&0
>W@1>W@2
/\  /\@3+A00&0
          &1Dp@0
//

Przetestuj te programy tutaj. Płytki cylindryczne, dołącz biblioteki i spacje dla pustych komórek muszą być sprawdzone.

Wejście i wyjście odbywa się poprzez STDIN / STDOUT.

Wyjaśnienie

Licznik:

Źródło licznika

Niebieska ścieżka odbiera dane wejściowe. Jeśli znak jest znakiem spacji (wartość ascii mniejsza niż 0x21), wybierana jest czarna ścieżka, która synchronizuje się ze ścieżką fioletową.

Purpurowa ścieżka po prostu zwiększa ilość marmuru przechowywanego w &1synchronizatorze za każdym razem, gdy wybierana jest czarna ścieżka.

Gdy nie ma już danych wejściowych, wybierana jest czerwona ścieżka, wypisująca liczbę białych znaków i wychodząca.

Rozłupnik:

Źródło Splittera

Program zaczyna się od niebieskiej ścieżki, która zapętla się, dopóki nie zostanie znaleziony znak spacji.

Po odzyskaniu znaku spoza białej ścieżki pobierana jest czarna ścieżka, która wypisuje ten znak i przenosi wykonanie na zieloną ścieżkę, która zapętla się i drukuje, aż do otrzymania znaku spacji. Wykonanie następnie przechodzi do fioletowej ścieżki, która zawiera 3Wlub trójdrożny rozdzielacz.

Lewa gałąź przenosi wykonanie na niebieską ścieżkę (a białe znaki są odrzucane, dopóki nie zostanie znaleziony znak inny niż biały).

Środkowa gałąź ustawia kopię danych wejściowych na 0 za pomocą ?0(generuje losową liczbę pomiędzy 0i 0) i dodaje 10 ( 0x0A= nowa linia), która jest następnie wyprowadzana.

Właściwą ścieżkę odrzuca się.


Wygląda na to, że rozdzielacz nie kończy się, jeśli występuje spacja.
Martin Ender,

12

CJam, 26 + 27 = 53 59 61 73 77 bajtów

Licznik

'!q_,\SN9c++SerS%:Qs,-QN*?

Rozłupnik

' !q_,\SN9c++SerS%:Qs,-QN*?

Jak to działa

Pomysł jest prosty, obliczyć liczbę białych znaków i podzielić ciąg znaków na kolejne serie białych znaków. Następnie wybierz jeden z nich na podstawie następującego faktu, który ' !oznacza , że not of space characterjest to fałsz, podczas gdy '!jest to !postać, która jest prawdziwa.

Rozszerzony kod:

'! / ' !                              "Get truthy or falsy value";
        q_                            "Read the input, make a copy";
          ,\                          "Take the length of the copy and swap";
            SN9c++                    "Get a string comprised of all Whitespaces";
                  Ser                 "Replace any occurrence of any character of"
                                      "the above string with space";
                     S%               "Split on one or more runs of space";
                       :Qs,           "Store this in Q, flatten to a string and take length";
                           -          "Subtract from total length to get count";
                            QN*       "Put the splitted array on stack and join newline";
                               ?      "Base on the truthy or falsy value, pick one to print";

Dane wejściowe pochodzą ze STDIN, a dane wyjściowe - STDOUT

Wypróbuj online tutaj


10

Mathematica, 44 + 43 = 87 97 bajtów

Myślałem, że dodam inny język do miksu.

Licznik:

StringCount[#,Whitespace]+0 1StringSpli t@#&

Rozłupnik:

String Count[#,Whitespace]+01StringSplit@#&

Wykorzystuje to funkcję Mathematiki, że separacja przestrzeni jest taka sama jak mnożenie. A to pomnożenie czegoś przez 0 to zawsze 0, a dodanie 0 do czegoś jest zawsze idempotentne.

W przypadku licznika najpierw liczymy białe znaki i dodajemy 0*1*StringSpli*t@#. StringSplii tnie są zdefiniowane, ale Mathematica używa obliczeń symbolicznych, więc traktuje je jako nieznaną zmienną i funkcję. 1*Jest idempotent (tak 0+), przy czym 0*włącza go do zera. Konieczne jest podzielenie tych StringSplitdwóch zmiennych, ponieważ 0czasami lista jest traktowana jako zwielokrotnienie wektora skalarnego, co daje wektor (listę) zer.

W przypadku rozdzielacza używam faktu, że Countrównież istnieje, ale nie analizuje ciągów. Próbuje policzyć wszystkie wyrażenia podrzędne pasujące do wzorca, ale Whitespacejest to wzorzec, który dotyczy tylko zawartości ciągu. Tak więc Countzawsze powróci 0, co powoduje Stringzniknięcie. Mnożenie podzielonej tablicy przez 01 = 1jest znowu idempotentne.


10

Rubin, 107 91 bajtów

Rozdzielacz (46 bajtów)

p
p=gets(p).split
puts p||$_.size-pp.join.size

Licznik (45 bajtów)

pp=gets(p).split
puts p||$_.size-pp.join.size

pjest predefiniowaną metodą, która bez argumentów zwraca tylko nil. Używamy tego na kilka sposobów. W rozdzielaczu inicjał pnic nie robi. gets(p)wczytuje wszystko ze standardowego wejścia, ponieważ separator jest pusty. Wywołujemy na tym wbudowaną metodę podziału i przypisujemy wynik p, więc teraz, gdy nie podano argumentów, zostanie przeanalizowana jako zmienna. puts p||...zwiera i drukuje każdy element pzmiennej do własnej linii.

W liczniku usuwamy pierwszy znak nowej linii, aby ppzamiast tego została przypisana podzielona tablica . Ponieważ nie przypisaliśmy się do ptej metody, wciąż jest to metoda zwracająca zero, więc druga część ||testów jest oceniana i przekazywana do puts. $_jest magiczną zmienną zawierającą wynik gets, więc łączna ilość białych znaków jest wielkością pomniejszoną o znaki niebiałe, które ppzawierają. Wydaje mi się, że powinien istnieć krótszy sposób liczenia, ale nie mogę go znaleźć, a w każdym razie używanie podzielonej tablicy w liczniku jest fajne.


7

Python, 169

W Pythonie jest to prawie zbyt łatwe!

Licznik:

def x(s):
 def y(s):
  return sum(map(str.isspace,s))
  return s.split()
 return y(s)

Rozłupnik:

def x(s):
 def y(s):
  return sum(map(str.isspace,s))
 return s.split()
 return y(s)

Różnią się tylko jedną spacją i nie robię żadnych sztuczek, takich jak dzielenie liczby lub nazwy zmiennej na pół :)


6

C 138 + 136 = 274

W każdym przypadku kod jest programem, który akceptuje dokładnie jeden argument wiersza poleceń i wypisuje wynik na standardowe wyjście. \tnależy zastąpić znakiem tabulacji. Jeśli chcesz przekazać argument zawierający tabulatory i znaki nowej linii, Twoim zadaniem jest dowiedzieć się, jak;).

Rachunkowość

#define strtok strpbrk
h=' \t\n';main(c,v,n)char**v;{for(n=- -c-1;v[n]=strtok(1[v],&h);n[v]++)v[!n]=0,puts(*v),c++;n*='d%';printf(&n,c-2);}

Rozdzielać

#define strtokstrpbrk
h=' \t\n';main(c,v,n)char**v;{for(n=--c-1;v[n]=strtok(1[v],&h);n[v]++)v[!n]=0,puts(*v),c++;n*='d%';printf(&n,c-2);}

6

JavaScript, 95 + 96 = 191 bajtów

Licznik:

c=(a,v)=>{v
v=a=a.split(RegExp(String.fromCharCode(92,115)));return v?a.length-1:a.filter(j=>j)}

Rozłupnik:

s=(a,v)=>{vv=a=a.split(RegExp(String.fromCharCode(92,115)));return v?a.length-1:a.filter(j=>!!j)}

Nie golfowany:

s=(a,v)=>{

    v  // this `v` is ignored, or combined with the next line to make `vv`

    // split array and store it in `a` and `v` (or alternatively `vv`)
    v = a = a.split(RegExp(String.fromCharCode(92,115)));

    return v?
            a.length-1        // return number of whitespace chars
            :
            a.filter(j=>j)    // return array without empty strings
    }

RegExp(String.fromCharCode(92,115)Linia tworzy regex białymi dopasowywania /\s/bez regex lub ciąg literałów.

W każdym programie używamy zmiennej vlub vv. Przechowujemy podzieloną tablicę w tej zmiennej ( vlub vv), a następnie rozgałęziamy nasze zachowanie na wartości v(tymczasem vvjest ignorowane). W ladzie vma prawdziwą wartość; w spliterze ma wartość falsy (ponieważ vvzamiast tego dostała wartość).


Alternatywnie: JavaScript, 250 bajtów

Mam inne rozwiązanie, które nie wygrywa żadnych nagród za zwięzłość, ale pomyślałem, że nadużywanie automatycznego wstawiania średnika JavaScript jest ciekawym wyzwaniem.

Licznik:

c=a=>{a=a.split(RegExp(String.fromCharCode(92,115)));x:for(i=2;i--;)for(o=i?a.length-1:a.filter(j=>j);1;){break x}return o}

Rozłupnik:

s=a=>{a=a.split(RegExp(String.fromCharCode(92,115)));x:for(i=2;i--;)for(o=i?a.length-1:a.filter(j=>j);1;){break
x}return o}

Licznik bez golfa:

s=a=>{
    a = a.split(
            RegExp(String.fromCharCode(92,115))   // split input on whitespace regex /\s/
        );  
    x:                             // x is a label for the outer loop
    for(i=2;i--;)                  // run this outer loop twice
        for(o=i?                   // if this is the first outer loop pass, 
               a.length-1          //    set `o` to number of whitespaces
               :                   // else, on second outer loop pass,
               a.filter(j=>j);     //    set `o` to split input (w/o empty strings)
            1;                     // 1 is truthy; run inner loop forever
            ) {
                break x;           // break out of outer loop
            }
    return o;                      // return `o`
}

Rozdzielacz jest dokładnie taki sam, z wyjątkiem linii:

break x;

jest teraz

break
x;

Automatyczne wstawianie średnika JavaScript zwykle nie kończy wcześniej instrukcji wieloliniowych, jeśli można je zrozumieć bez podziału linii, ale nie toleruje podziału linii po return, continuelub break. Dlatego linia jest odczytywana po prostu jako break, która wyłamuje się tylko z wewnętrznej pętli, zamiast zrywając z zewnętrznej pętli. Wykonywane o = a.filter(j=>j)jest wówczas zachowanie „drugiego przejścia” (w przeciwieństwie do pominięcia w liczniku), ponieważ zewnętrzna pętla otrzymuje drugie przejście.


Czy !!xróżni się od automatycznej Boolkonwersji?
l4m2

@ l4m2 To nie jest! Usunąłem go, ponieważ filterauto-bools zwraca oddzwonienie według tych samych zasad, co !!. Dzięki!
apsillers

5

Python, 228 198 182 166 146 145 bajtów

Licznik ( 72 bajty ):

ior1=0
w=lambda i:i.split()if ior1 else sum(ord(c)in(9,10,32)for c in i)

Rozdzielacz ( 73 bajty ):

ior1=0
w=lambda i:i.split()if i or 1else sum(ord(c)in(9,10,32)for c in i)

ior1jest zmienną falsey, ale i or 1jest prawdą. To główna sztuczka.


Czy to się nie psuje, jeśli ipusty ciąg dla rozdzielacza? Można to naprawić, zmieniając iorbna ior1, co pozwala również zapisać postać pomiędzy 1i else.
isaacg

@isaacg Całkowicie zapomniałem, że możesz mieć liczby w nazwach zmiennych! Dziękuję <3
metro

5

Befunge 98, 61 + 59 = 120

Licznik:

~:'!-0`#v_ >$1+#@ #. #
 @#,#$ #<_v#`0-!':~ # .#
  ,#$ #+55<v

Rozłupnik:

~:'!-0`#v_ >$1+#@ #.#
 @#, #$#<_v#`0-!':~ #.#
  , #$#+55<v

4

Bash, 75 + 79 = 154 bajtów

Polega to na tym, że bash będzie mógł kontynuować wykonywanie, nawet jeśli niektóre wiersze lub części wiersza skryptu są zniekształcone (w niektórych okolicznościach). Biała spacja służy do wyłączania znaków ucieczki dla niektórych nawiasów klamrowych i do łamania rury poprzez umieszczenie jej w nowej linii.

Rozłupnik:

echo $((`echo $1|wc -w`+${#1}-$(\)\)\)
for a in $1;do echo $a;done|wc -c)))

Licznik:

echo $((`echo $1|wc -w`+${#1}-$(\ )\ )\ )
for a in $1;do echo $a;done
|wc -c)))

Dane wejściowe są za pomocą argumentu wiersza poleceń, dane wyjściowe - przez standardowe wyjście.

Ponieważ zależy to od zachowania błędu bash, użytkownik powinien zignorować stderr.

Przykładowy przebieg (pokazujący dane wejściowe z nową linią i wieloma ciągłymi spacjami):

# bash counter.sh "abc def
gh   ij k" 2>/dev/null
6
# bash splitter.sh "abc def
gh   ij k" 2>/dev/null
abc
def
gh
ij
k

4

Rubinowy, 114 + 116 107 + 109 = 216 bajtów

To nie może konkurować z rozwiązaniem ruby ​​autorstwa histokryta, ale pomyślałem, że i tak warto go odłożyć.

Użyłem $zdo nili nil.to_sdlaString.new

Dodatkowym znakiem białej spacji, który dodaję na końcu danych wejściowych, jest wymuszenie dodania ostatniego słowa do tablicy ( r) - słowo jest dodawane tylko na końcu tablicy, gdy znak białej spacji następuje po znaku innym niż biały. Alternatywą było dodanie kolejnej r<<w if wpo each_bytebloku.

Rachunkowość

->s{r=[]
n=-1
w=$z
(s+9.chr).each_byte{|b|if b<33
r<<w if w
w=$z
n+=1
else
w=w.to_s+b.chr
end}
$zorr ?r:n}

Rozdzielać

->s{r=[]
n=-1
w=$z
(s+9.chr).each_byte{|b|if b<33
r<<w if w
w=$z
n+=1
else
w=w.to_s+b.chr
end}
$z or r ?r:n}

Ach, nie byłem pewien co do orzeczenia w tej sprawie. Zmieniłem go, aby używał if-else zamiast operatora trójskładnikowego - nigdy więcej literałów łańcuchowych.
alexanderbird

3

Haskell , 53 + 55 = 108 36 + 38 = 74 bajty

Licznik

f=do
 pure(length.filter(<'!'))words

Rozłupnik

f=do
 pure(length.filter(<'!'))
 words

To rozwiązanie wykorzystuje fakt, że w Haskell funkcje są instancją klasy typu Monad, a zatem mogą być używane jako akcje monadyczne w notacji do.

W pierwszym przypadku wynikowa funkcja do-block jest pierwszym argumentem pure(który jest zasadniczo constdla typu funkcji), co powoduje, że licznik jest końcowym wynikiem, a rozdzielacz jest odrzucany.

W drugim przypadku purejest stosowany tylko do jednego argumentu, co czyni go funkcją zwracającą inną funkcję (licznik). Jednak wynik nigdy nie jest wykorzystywany, a zatem odrzucany. Ostatecznym rezultatem jest druga linia do-block, rozdzielacz.


Niezłe podejście! [' ','\t','\n']można skrócić do " \t\n".
Laikoni

@Laikoni Opis dopuszcza tylko literały znakowe, bez literałów łańcuchowych i wyrażeń regularnych
siracusa

2
Ponieważ wyzwanie nie wymaga od ciebie obsługi większości znaków kontrolnych, możesz to skrócić, (<'!')testując spacje.
Ørjan Johansen

2

Java 8, 187 + 188 = 375

Przede wszystkim chciałbym powiedzieć, że ta odpowiedź jest w dużej mierze oparta na @ Ypnypn. Zasadniczo wymieniłem niektóre części na krótsze (w tym część zależną od białych znaków, której IMO jest najważniejsze w tym wyzwaniu), ale kod funkcjonalny jest w większości taki sam.

Policz białe znaki , 187 (zwraca int):

Object f(String s){String r=new String(new char[]{92,115});int a=0;return a--+a>0?s.chars().filter(c->c>8&c<11|c==32).count():java.util.Arrays.stream(s.split(r)).filter(t->t.length()>0);}

Podział na białe znaki , 188 (zwraca Stream<String>):

Object f(String s){String r=new String(new char[]{92,115});int a=0;return a- -+a>0?s.chars().filter(c->c>8&c<11|c==32).count():java.util.Arrays.stream(s.split(r)).filter(t->t.length()>0);}

2

J, 48 + 49 = 97 znaków

Dwie funkcje przyjmujące i zwracające pojedynczy argument. Wykorzystałem najbrzydszy sposób, w jaki mogłem wymyślić, aby pokonać regułę z tą samą białą spacją, więc prawdopodobnie są postacie, które można uratować, znajdując bardziej sprytną drogę.

(aa[aa=.+/@a=.a:-.~(e.u:)&9 10 32 :(<;._1~1,}.))      NB. count
(a a[aa=.+/@a=.a:-.~(e.u:)&9 10 32 :(<;._1~1,}.))     NB. split

Definiujemy czasownik, aaby miał dwie różne akcje, w zależności od tego, czy jest używany z jednym argumentem, czy z dwoma. Z jednym argumentem (e.u:)&9 10 32sprawdza, czy każdy znak jest spacją, czy nie. Jest to z dwoma argumentami, a:-.~(<;._1~1,}.)które biorą wektor boolowski po prawej stronie i przecinają lewy argument w tych pozycjach, odrzucając wszelkie puste cięcia za pomocą a:-.~.

Następnie określamy, że aawynikiem będzie liczba wartości True a, co ma sens tylko z jednym argumentem. Wreszcie używamy aalub w a azależności od tego, czy chcemy policzyć, czy podzielić białe znaki ciągu. aadziała zgodnie z oczekiwaniami.

Powodem a ajest to, że kiedy J widzi (f g)y, bierze pod uwagę (f g)hak i ocenia go w podobny sposób y f (g y). W tym przypadku fjest to diadyk, anad którym wykonuje się wycinanie, i gjest a[aa, który oblicza sumę aa, wyrzuca ją i ponownie oblicza (monadycznie) a.

W REPL:

   (aa[aa=.+/@a=.a:-.~e.&(u:9 10 32) :(<;._1~1,}.))   '  123',TAB,'-_-   abc',LF,'def'
7
   (a a[aa=.+/@a=.a:-.~e.&(u:9 10 32) :(<;._1~1,}.))  '  123',TAB,'-_-   abc',LF,'def'
+---+---+---+---+
|123|-_-|abc|def|
+---+---+---+---+

2

Bash, 54 + 50 = 104 bajty

Licznik

a=$IFS
IFS=
cat()(tr -cd $a|wc -c)
printf %s \\n$1|cat

Rozłupnik

a=$IFSIFS=ca
t()(tr-cd$a|wc-c)
printf %s\\n $1|cat

1

Perl, 37 + 38 = 75

Licznik :

sub f{($_)=@_;(y/   - //,[split])[0.1]}

Splitter :

sub f{($_)=@_;(y/   - //,[split])[0 .1]}

1

Perl 6, 31 + 32 = 63 bajty

Licznik

{?^1??.words!!+grep 33>*,.ords}

Wypróbuj online!

?^1jest analizowany, jak ?^ 1co powoduje zastosowanie logicznego operatora negacji do 1, w wyniku czego False.

Rozłupnik

{? ^1??.words!!+grep 33>*,.ords}

Wypróbuj online!

? ^1konwertuje zakres 0..0 na Bool, w wyniku czego True.


0

Python 2, 98

Podział (49)

Zwraca tokeny na liście.

f=lambda s:[sum(map(str.isspace,s))]and s.split()

Liczenie (49)

Zwraca listę o długości jeden zawierającą liczbę znaków spacji. Najprawdopodobniej spowoduje to błąd w czasie wykonywania, ale funkcji fmożna użyć po wykonaniu kodu.

f=lambda s:[sum(map(str.isspace,s))]
ands.split()

0

C (gcc) , 88 + 89 = 177 bajtów

Rozłupnik

i,n,x,c;f(char*s){x=n=i=0;for(x+++n;c=*s++;c*x&&putchar(c))i=c<33?n++,c=i*10,0:1;x=n-1;}

Rozłupnik

Licznik

i,n,x,c;f(char*s){x=n=i=0;for(x+ ++n;c=*s++;c*x&&putchar(c))i=c<33?n++,c=i*10,0:1;x=n-1;}

Licznik

Zniszczony

Pobiera dane wejściowe jako argument funkcji. Funkcja zliczania zwraca liczbę białych znaków. Funkcja podziału używa STDOUT dla swoich danych wyjściowych (ale przy okazji zwraca również liczbę białych znaków minus jeden).

i,                      Flag signalling whether we are inside a word.
n,                      Number of whitespace encountered.
x,                      Flag signalling whether or not we should output the words.
c;                      Current character.
f(char*s){              Take input string as an argument.
x=n=i=0;for(            Initialise everything and start loop.
x+++n;                  SPLITTER ONLY: Interpreted as x++ +n, meaning x is set to 1 and n stays 0.
x+ ++n;                 COUNTER ONLY: Inverse of the above. Sets n to 1, and x stays 0.
c=*s++;                 Sets c to current char and increment string pointer, end loop if end of string.
c*x&&putchar(c))        Only output c if x is 1 and c is non-zero, which only happens if we left a word.
i=c<33?                 Since input contains only printable ASCII or whitespace, anything below 33 is whitespace.
       n++,             ...if that is the case, increment the whitespace counter (n)
           c=i*10,      ...and set c to newline (10), but only if we just left a word (if i is 1)
                  0:    ...and set i to 0.
                    1;  If not a whitespace, set i to 1, signalling we are inside a word.
x=n-1;}                 Implicitly returns n-1, which is the number of whitespaces if we are in the counter function.

0

Zsh , 35 + 35 = 70 bajtów

  • Żaden program / funkcja nie może zawierać żadnych literałów ani wyrażeń regularnych

Nie jestem pewien, czy się [^$IFS]kwalifikuje, ponieważ jest on używany do dopasowania wzorca. Oto rozwiązanie 45 + 45 w przypadku, gdy zostanie zbanowany.


Rozdzielać:

:<<<${#1//[^$IFS]} 
:
<<<${(F)${=1}}

Liczyć:

:
<<<${#1//[^$IFS]}
:<<<${(F)${=1}}

:Wbudowane jest equivilent celu trueużywamy go jako coś pomiędzy komentarz i / dev / null (ponieważ komentarze są niedozwolone) rurami niechciany ekspansję na niego.

Zsh ma wbudowaną funkcję podziału na białe znaki ${=var}. Utrudnia to wykonanie jakiejkolwiek logicznej kombinacji poza wykonaniem obu i odrzuceniem tej, której nie chcemy.

Wypróbuj online!

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.