Значительный пробел


55

Мы определяем пробел как любой из трех символов: tab (0x09), символ новой строки (0x0A) или пробел (0x20).

Для этого вам нужно написать две программы или функции на одном языке программирования, которые выполняют следующие задачи:

  1. Подсчитайте пробельные символы в заданной строке. Например, вход

      123 -_-   abc
    def
    

    вернул бы 7 (при условии, что нет завершающего символа новой строки).

  2. Разбить заданную строку при последовательных пробелах. Если строка начинается или заканчивается пробелом, пустые строки не должны возвращаться на концах. Например, тот же вход

      123 -_-   abc
    def
    

    вернется ["123", "-_-", "abc", "def"].

В любом случае вы можете получить ввод через STDIN, аргумент командной строки или аргумент функции, чтобы вернуть результат или распечатать его как STDOUT. Для второй программы, если вы решите печатать в STDOUT, напечатайте каждую строку в отдельной строке без кавычек.

Для обеих программ вы можете предположить, что вход содержит только печатные ASCII (от 0x20 до 0x7E) и пробелы.

Теперь вот подвох:

  • Если все пробелы удалены из обеих программ / функций, результирующие строки должны быть идентичными. То есть ваши два представления могут отличаться только количеством и расположением пробельных символов.
  • Ни одна из программ / функций не может содержать строковые или регулярные литералы (символьные литералы в порядке, если у вашего языка есть обозначенный тип символов).
  • Ни одна из программ / функций не может содержать никаких комментариев.
  • Вы не должны читать исходный код программы, прямо или косвенно.

Это код гольф. Ваша оценка - это сумма размеров обоих решений (в байтах). Самый низкий балл побеждает.

Leaderboards

Следующий фрагмент стека генерирует как регулярную таблицу лидеров, так и обзор победителей по языкам. Поэтому, даже если ваш предпочтительный язык не позволяет вам выиграть весь вызов, почему бы не попытаться занять место во втором списке? Мне было бы очень интересно посмотреть, как люди решают эту проблему на разных языках!

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

# Language Name, N bytes

где Nесть общий размер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:

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

Вы также можете включить отдельные подсчеты до общего подсчета, например,

# Python 2, 35 + 41 = 76 bytes

Последний номер, который не вычеркнут, будет использоваться фрагментом.

<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
Этот список лидеров это круто!
Цифровая травма

5
Звучит так, как если бы ответ на
Whitespace

1
@ nyuszika7h Да, конечно, но все равно не будет особенно коротким.
Мартин Эндер

7
Значительные пробелы, поэтому не пробелы с выгодами или чем-то ...
CorsiKa

Ответы:


15

Pyth, 16 + 15 = 31 байт

Попробуй это здесь .

Счетчик:

L@,cb)sm!cd)b1 0

Splitter:

L@,cb)sm!cd)b10

Каждый из них определяет функцию, yкоторая принимает строковый ввод для решения желаемой задачи.

Спасибо @FryAmTheEggman за идею использования функции модульной индексации в списках в Pyth для бритья персонажа.

Тестовые случаи:

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

Объяснение:

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 байт

Счетчик:

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

Splitter:

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

Для счетчика мы используем тот факт, что в Python все нормально, когда в строке есть только выражение. Это необходимо , чтобы разделить +1и , 0<9or x.split()чтобы остановить NameErrorот броска, так как 0<9время Trueпредотвращает x.split()от оцениваемого из - за короткого замыкания.

Для разделителя, поскольку количество пробелов всегда неотрицательно, sum(y.isspace()for y in x)+10<9всегда Falseи функция разделения вступает в игру.


Альтернатива 1, 59 + 60 = 119 байт

Счетчик:

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

Splitter:

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

Результаты как подсчета, так и разбиения сохраняются в двухэлементном списке. Список индексируется либо min([1]), возвращая минимум содержащего один элемент списка 1, либо m in([1]), который возвращает False(эквивалентно 0) то, что mне содержится в [1].


Альтернатива 2, 67 + 69 = 136 байт

Счетчик:

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

Splitter:

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

Как и выше, результаты подсчета и разделения сохраняются в двухэлементном списке. sortedявляется встроенной функцией, которая является истинным значением, поэтому not sortedвозвращает False(эквивалентно 0). Ибо not s or ted, поскольку sэто функция, а также правда, not sесть Falseи ted = 1возвращается.


Альтернатива 3, 59 + 60 = 119 байт

Счетчик:

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

Splitter:

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

Это функция, в которой результат сплиттера сохраняется в переменной a, а результат счетчика сохраняется в переменной a1. Как и раньше, в этом случае Python прекрасно работает только с выражением в строке 1. Разделение a1определяет, что нужно вернуть из функции.


22
Я бы снова +1 за not sorted.
Мартин Эндер

Является ли новая строка между +1и 0<9or x.split()необходимо?
Исаак

1
@isaacg Если вам небезразличны исключения, тогда да
Sp3000

Вы можете сбрить 3 байта с помощью m=lambda x:sum(y.isspace()for y in x)+00and x.split()и m=lambda x:sum(y.isspace()for y in x)+0;0and x.split()(делая эту точку с запятой новой
строкой,

@cjfaure Я не думаю, что первый работает как сплиттер, если нет пробелов
Sp3000

16

Ява 8, 239 + 240 = 479

Подсчет пробелов (возвращает целое число)

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);}

Разделить на пустое пространство (возвращает 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);}

Объяснение:

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);
}

Для меня это выглядит блестяще. +1
Родольфо Диас

Довольно хорошо, учитывая, что Java должна быть худшим языком для игры в гольф кода.
tbodt

13

Пробел, 75 + 153 = 228

Пробелы, табуляции и переводы строк заменены на STL соответственно и свернуты для удобства чтения. Преобразовать в правильный файл пробела с tr -d \\n | sed 'y/STL/ \t\n/'.

счетчик

SSSLLSSLSSSTSSSSSLSLSSLSTLTSTTTSLSLTSSLTSSTLTTLSSSTLTSSSLSLLLSSSLS
LLSLLTLST

Разветвитель

SSSTLSSSLTTSLSSTLSSSLSLSTLTSTTTSLSSLSLTSLSSSTSSSSTLTSSTLTTTTLSSSTL
SLSTTSLSLSLLSSTTLSSSTSTSLSSSTLTTTLTSTSLTLSSSSSTLSSSLTTSLSSTSLLSLTL
LSSSLTLSSLSLTLLSSLLLL

2
Мне было интересно, сколько времени это займет ...;)
Мартин Эндер

4
С пробелами это становится двумя отдельными проблемами игры в гольф.
tbodt

13

Марбелоус, 103 + 92 = 195

Счетчик:

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

Splitter:

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

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

Вход и выход через STDIN / STDOUT.

объяснение

Счетчик:

Счетчик Источник

Синий путь получает вход. Если символ является символом пробела (значение ascii меньше 0x21), берется черный путь, который синхронизируется с фиолетовым путем.

Фиолетовый путь просто увеличивает мрамор, хранящийся в &1синхронизаторе, каждый раз, когда берется черный путь.

Когда больше нет ввода, берется красный путь, печатается количество пробельных символов и завершается.

Splitter:

Источник разветвителя

Программа начинается с синего пути, который повторяется, пока не будет найден непробельный символ.

Когда извлекается непробельный символ, берется черный путь, который печатает этот символ и перемещает выполнение к зеленому пути, который зацикливается и печатается до получения пробельного символа. Затем выполнение продолжается до фиолетового пути, который содержит 3Wили трехсторонний разделитель.

Левая ветвь перемещает выполнение в синий путь (и пробелы отбрасываются до тех пор, пока не будет найден непробельный символ).

Средняя ветвь устанавливает копию входного значения в 0 с помощью ?0(генерирует случайное число между 0и 0) и добавляет 10 ( 0x0A= перевод строки), который затем выводится.

Правильный путь отбрасывается.


Кажется, что сплиттер не завершается, если есть пробел.
Мартин Эндер

12

CJam, 26 + 27 = 53 59 61 73 77 байт

счетчик

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

Разветвитель

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

Как это устроено

Идея проста: рассчитать количество пробелов и разбить строку на последовательные пробелы. Затем выберите один из них основан на следующем факте , что ' !средство , not of space characterкоторое является falsy, в то время как '!это !символ, который truthy.

Расширенный код:

'! / ' !                              "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";

Вход от STDIN и выход для STDOUT

Попробуйте онлайн здесь


10

Mathematica, 44 + 43 = 87 97 байт

Я думал, что добавлю еще один язык в микс.

Счетчик:

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

Splitter:

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

Это использует функцию Mathematica, заключающуюся в том, что разделение пространства такое же, как умножение. И умножение чего-либо на 0 всегда равно 0, а добавление 0 к чему-либо всегда идемпотентно.

Для счетчика мы сначала подсчитываем пробел и добавляем 0*1*StringSpli*t@#. StringSpliи tне определены, но Mathematica использует символьные вычисления, поэтому он просто обрабатывает их как неизвестную переменную и функцию. 1*Идемпотентна (как 0+), то 0*превращает его в ноль. Необходимо разделить их StringSplitна две переменные, потому что 0иногда список обрабатывается как умножение на скалярный вектор, что приводит к вектору (списку) нулей.

Для сплиттера я использую тот факт, что он Countтакже существует, но не просматривает строки. Он пытается подсчитать все подвыражения, соответствующие шаблону, но Whitespaceэто шаблон, который применяется только к строковому содержимому. Так Countвсегда будет возвращаться 0, что делает Stringисчезновение. Умножение расщепленного массива 01 = 1снова идемпотентно.


10

Рубин, 107 91 байт

Сплиттер (46 байт)

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

Счетчик (45 байт)

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

pэто предопределенный метод, который без аргументов просто возвращает nil. Мы используем это несколькими способами. В сплиттере инициал pничего не делает. gets(p)читает все из стандартного ввода, так как разделитель равен нулю. Мы вызываем для этого встроенный метод split и присваиваем результат p, поэтому теперь, когда ему не заданы аргументы, он будет проанализирован как переменная. puts p||...закорачивает и печатает каждый элемент pпеременной в отдельной строке.

В счетчике мы удаляем первую новую строку, чтобы ppвместо нее был назначен разделенный массив . Поскольку мы не присваиваем p, это все еще метод с нулевым возвратом, поэтому вторая часть ||получает и оценивается puts. $_является магической переменной, содержащей результат gets, поэтому общее количество пробелов - это размер минус непробельные символы, которые ppсодержат. Я чувствую, что должен быть более короткий способ подсчета, но я не могу его найти, и, во всяком случае, использование разделенного массива в счетчике - это весело.


7

Питон, 169

Это почти слишком легко сделать в Python!

Счетчик:

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

Splitter:

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

Они отличаются только одним пробелом, и я не делаю никаких хитростей, таких как деление числа или имени переменной пополам :)


6

С 138 + 136 = 274

В каждом случае код - это программа, которая принимает ровно один аргумент командной строки и выводит результат в стандартный вывод. \tдолжен быть заменен символом табуляции. Если вы хотите передать аргумент, содержащий вкладки и символы новой строки, то ваша задача - выяснить, как;).

Counting

#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);}

расщепляющий

#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 байт

Счетчик:

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

Splitter:

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

Ungolfed:

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)Строка создает пробельные сопоставления регулярных выражений /\s/без регулярных выражений или строковых литералов.

В каждой программе мы используем переменную vили vv. Мы сохраняем разделенный массив в эту переменную ( vили vv), а затем разветвляем наше поведение по значению v(между тем, vvигнорируется). В прилавке vимеет истинное значение; в разделителе он имеет ложное значение (потому vvчто вместо этого получил значение).


Альтернатива: JavaScript, 250 байт

У меня есть другое решение, которое не приносит выигрышей за краткость, но я подумал, что было бы интересным испытать злоупотребление поведением автоматической вставки точек с запятой в JavaScript.

Счетчик:

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}

Splitter:

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}

Неуправляемый счетчик:

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`
}

Сплиттер точно такой же, за исключением строки:

break x;

сейчас

break
x;

Автоматическая вставка точек с запятой в JavaScript обычно не прекращает заявления многострочных рано , если они могут быть поняты без разрыва строки, но он не терпит разрывы строк после return, continueили break. Следовательно, строка читается просто как break, которая разрывается только из внутреннего цикла, а не из внешнего цикла. o = a.filter(j=>j)Затем выполняется поведение «второго прохода» (вместо пропуска в счетчике), поскольку внешнему циклу дается второй проход.


Отличается ли !!xавтоматическое Boolпреобразование?
l4m2

@ l4m2 Это не так! Я удалил его, так как filterавто-bools его обратный вызов возвращается по тем же правилам, что и !!. Спасибо!
Апсиллеры

5

Python, 228 198 182 166 146 145 байт

Счетчик ( 72 байта ):

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

Разделитель ( 73 байта ):

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

ior1переменная Фальси, но i or 1это правда. Это главный трюк.


Разве это не нарушается, если iпустая строка для сплиттера? Может быть исправлено путем изменения iorbна ior1, что также позволяет сохранить символ между 1и else.
Исаак

@isaacg Я полностью забыл, что у тебя могут быть числа в именах переменных! Спасибо <3
подземный

5

Befunge 98, 61 + 59 = 120

Счетчик:

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

Splitter:

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

4

Баш, 75 + 79 = 154 байта

Это основано на том, что bash может продолжать выполнение, даже если некоторые строки или части строки скрипта искажены (в некоторых случаях). Пробелы используются для деактивации escape-кодов для некоторых закрывающих скобок и для разрыва канала, помещая его в новую строку.

Splitter:

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

Счетчик:

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

Ввод через аргумент командной строки, выход через stdout.

Поскольку это зависит от поведения ошибок bash, пользователь, как ожидается, будет игнорировать stderr.

Пример выполнения (показывает ввод с новой строкой и несколькими смежными пробелами):

# 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

Ruby, 114 + 116, 107 + 109 = 216 байт.

Это не может конкурировать с рубиновым решением гистократа, но я подумал, что в любом случае стоило бы мириться.

Я использовал $zдля nilи nil.to_sдляString.new

Дополнительный символ пробела, который я добавляю в конец ввода, - это принудительное добавление последнего слова в массив ( r) - слово добавляется только в конец массива, когда символ пробела следует за непробельным символом. Альтернативой было добавление еще одного r<<w if wпосле each_byteблока.

Counting

->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}

расщепляющий

->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}

Ах, я не был уверен насчет решения по этому вопросу. Я изменил его, чтобы использовать if-else вместо тернарного оператора - больше никаких строковых литералов.
alexanderbird

3

Haskell , 53 + 55 = 108 36 + 38 = 74 байта

счетчик

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

Разветвитель

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

Это решение использует тот факт, что в Haskell функции являются экземпляром класса типа Monad и, следовательно, могут использоваться как монадические действия в do-нотации.

В первом случае результирующая функция do-блока является первым аргументом pure(который по существу относится constк типу функции), что делает счетчик конечным результатом, а сплиттер отбрасывается.

Во втором случае pureприменяется только один аргумент, что делает его функцией, возвращающей другую функцию (счетчик). Тем не менее, результат никогда не используется и, следовательно, отбрасывается. Окончательный результат - вторая строка do-block, разделитель.


Хороший подход! [' ','\t','\n']можно сократить до " \t\n".
Лайкони

@Laikoni В описании допускаются только символьные литералы, без строковых или регулярных выражений
siracusa

2
Поскольку для выполнения задачи не требуется обрабатывать большинство управляющих символов, вы можете сократить это, используя (<'!')для проверки пробелов.
Эрджан Йохансен

2

Ява 8, 187 + 188 = 375

Прежде всего, я хотел бы сказать, что этот ответ в значительной степени основан на @ Ypnypn's. Я в основном заменил некоторые части более короткими (включая часть, зависящую от пробелов, которая IMO является наиболее важной в этой задаче), но функциональный код в основном такой же.

Посчитайте пробел , 187 (возвращает 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);}

Разделить пробел , 188 (возвращается 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 символов

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

(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

Мы определяем глагол, aчтобы иметь два разных действия, в зависимости от того, используется ли он с одним аргументом или с двумя. С одним аргументом, (e.u:)&9 10 32который проверяет, является ли каждый символ пробелом или нет. С двумя аргументами это так a:-.~(<;._1~1,}.), который берет логический вектор справа и обрезает левый аргумент в этих позициях, отбрасывая любые пустые сокращения с помощью a:-.~.

Затем мы определяем aaчисло значений True в результате a, что имеет смысл только с одним аргументом. Наконец, мы используем aaили в a aзависимости от того, хотим ли мы посчитать или разделить пробел строки. aaработает как положено.

Причина в a aтом, что когда J видит (f g)y, он рассматривает (f g)хук и оценивает его следующим образом y f (g y). В этом случае f- это диадический aвыше, который выполняет резку, и gкоторый a[aa, который вычисляет сумму из aa, выбрасывает ее и вычисляет (монадический) aснова.

На 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 байта

счетчик

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

Разветвитель

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

1

Perl, 37 + 38 = 75

Счетчик :

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

Сплиттер :

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

1

Perl 6, 31 + 32 = 63 байта

счетчик

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

Попробуйте онлайн!

?^1разбирается так, ?^ 1что применяет логический оператор отрицания к 1, в результате чего False.

Разветвитель

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

Попробуйте онлайн!

? ^1преобразует диапазон 0..0 в Bool, в результате чего True.


0

Python 2, 98

Расщепление (49)

Возвращает токены в списке.

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

Подсчет (49)

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

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

0

C (gcc) , 88 + 89 = 177 байт

Разветвитель

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;}

Разветвитель

счетчик

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;}

счетчик

Наезжать

Принимает ввод как аргумент функции. Функция подсчета возвращает количество пробелов. Функция расщепления использует STDOUT для своего вывода (но, кстати, также возвращает количество пробелов минус один).

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 байт

  • Ни одна из программ / функций не может содержать строковые или регулярные литералы

Я не уверен, соответствует ли это [^$IFS]требованиям, так как он используется в сопоставлении с образцом. Вот 45 + 45 решение в случае, если оно заблокировано.


Трещина:

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

Количество:

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

:Встроенная команда equivilent к true, мы используем его как нечто среднее между комментарием и / Dev / нуль (так как комментарии запрещенную) по конвейеру нежелательного расширения к нему.

Zsh имеет встроенную функцию для разбиения на пробелы, это существо ${=var}. Это затрудняет создание какой-либо логической комбинации, кроме выполнения обоих и отбрасывания того, который нам не нужен.

Попробуйте онлайн!

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