Как быстро я ворошу?

19

Вступление

Спидометр моей машины был взломан! Вместо того, чтобы показать мне, как быстро я еду, он просто показывает: "Vroooom!" Пожалуйста, помогите мне знать, как быстро я иду.

Вызов

Возьмите строку в качестве ввода и проверьте, соответствует ли она регулярному выражению /^[Vv]ro*m!$/m. В английском языке это означает, что любая строка строки должна начинаться с заглавной или строчной буквы v, затем строчной буквы r, затем любой суммы (включая ноль) строчной буквы o, а затем точной строки m!. Могут быть и другие строки, но строка Vroom должна быть на отдельной строке.

Если вы найдете совпадение, вы должны посчитать количество o's в строке Vroom и вывести его. Однако, если вы не найдете соответствия, вы должны вывести любое значение по умолчанию, которое не может быть выведено иначе (например, -1или пустую строку)

Напоминания

счет

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

Контрольные примеры

вход

Vrom!

Выход 1

вход

vrooooooom!

Выход 7

вход

Hello, Vroom!

Выход (none)

вход

Foo bar boo baz
Vrooom!
hi

Выход 3

вход

Vrm!ooo

Выход (none)

вход

PPCG puzzlers pie

Выход (none)

вход

hallo
vROOOm!

Выход (none)

FireCubez
источник

Ответы:

4

Python 2 , 56 53 байта

lambda x:len(re.search('^[Vv]r(o*)m!$',x,8).group(1))

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

Основное регулярное выражение и группировка, использует флаг re.MULTILINE (который имеет значение 8) и re.search, чтобы гарантировать, что он работает для многострочных входов. Вызывает исключение, когда совпадение не найдено. Спасибо @ovs за -3 байта из (re.M == 8)чаевых.

Shamtam
источник
1
Добро пожаловать в PPCG! Я переформатировал ваш ответ, чтобы он выглядел немного лучше, если вы недовольны моим редактированием, вы всегда можете откатиться назад. Btw. Я предлагаю ссылку на что-то вроде tio.run , чтобы люди могли легко проверить ваш ответ.
მოიმო
re.Mимеет значение 8, так что можете просто использоватьre.search(regex,x,8)
ovs
4

R , 62 60 58 44 байта

nchar(grep("^[Vv]ro*m!$",readLines(),v=T))-4

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

@Giuseppe с 14 байтами в гольф.

Оригинальный подход с объяснением:

function(x)attr(el(regexec("(?m)[Vv]r(o*)m!$",x,,T)),"m")[2]

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

R имеет семь функций сопоставления с образцом. Наиболее часто используемые из них grep, greplи sub, но вот хорошее применение для regexec.

regexecдает вам кучу вещей, одна из которых - длина любой захваченной подстроки, в данном случае это (o*)часть многострочного регулярного выражения.

Материал attr(el .... "m")[2]- это гольф-способ получить желаемое количество.

Возвращает, NAесли нет совпадений.

НГМ
источник
У меня есть 44-байтовый подход ... Не собираюсь публиковать его, если вы не хотите, чтобы я.
Джузеппе
@ Джузеппе не уверен, почему нет? Особенно если это принципиально иное.
НГМ
3

JavaScript (Node.js) , 41 байт

a=>(l=/[Vv]r(o*)m!/.exec(a))&&l[1].length

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

Луис Фелипе Де Иисус Муньос
источник
Это терпит неудачу дляvroooooooooooom!x\nvrom!
მოიმო
1
Поскольку мы можем выйти с ошибкой, если совпадение не найдено, вы можете сделать это для -3 байта, исправляя проблему @BMO, упомянутую выше в процессе.
Лохматый
Несокрушенному 41 определенно все еще 41
Программы
@ Shaggy Что пространство [1]. lengthдля?
l4m2
@ l4m2, опечатка! Я не заметил его на своем телефоне, потому lengthчто в любом случае перешел на новую строку.
Лохматый
3

Powershell, 62 58 53 48 байт

"$($args|sls '(?m-i)^[Vv]ro*m!$'|% M*)".Length-4

возвращает число oв первом Vroom!или -4, если Vroom!не найден.

Примечания:

  • slsэто псевдоним для Select-String ;
  • (?m-i) внутри регулярное выражение означает:
    • Используйте многострочный режим. ^и $соответствует началу и концу строки вместо начала и конца строки.
    • Используйте регистрозависимое соответствие
  • |% M*является ярлыком для свойства Matches, которое дает первое совпадение, потому что мы не используем -AllMatchesпараметр.

Тестовый скрипт:

$f = {

"$($args|sls '(?m-i)^[Vv]ro*m!$'|% M*)".Length-4

}

@(
,('Vrom!',1)
,('vrooooooom!',7)
,('Hello, Vroom!',-4)
,('Foo bar boo baz
Vrooom!
hi',3)
,('Vrm!ooo',-4)
,('PPCG puzzlers pie',-4)
,('hallo
vROOOm!',-4)
,('
Vrooom!
Vrooooom!
',3)        # undefined behavior.
,('vrm!',0) # :)
) | % {
    $n,$expected = $_
    $result = &$f $n
    "$($result-eq$expected): $result"
}

Выход:

True: 1
True: 7
True: -4
True: 3
True: -4
True: -4
True: -4
True: 3
True: 0
Mazzy
источник
2

PowerShell , 83 байта

($args-split"`n"|%{if(($x=[regex]::Match($_,"^[Vv]ro*m!$")).success){$x}}).length-4

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

-splits ввод $argsна `newlines, направляет их в цикл for. На каждой итерации мы проверяем, [regex]::Matchявляется ли наш тип .successили нет. Если это так, мы оставляем $x(объект результатов regex) на конвейере. Вне цикла мы берем .lengthсвойство - если это объект результатов регулярного выражения, это длина совпадения (например, «Vroom!» Будет 6); если это не объект результатов регулярного выражения, длина равна нулю. Затем мы вычитаем, 4чтобы убрать отсчеты для Vrm!и оставить это на конвейере. Вывод неявный. Выводит a, -4если совпадений не найдено.

AdmBorkBork
источник
sls "^[Vv]ro*m!$"?
Маззи
@mazzy Как это будет работать для многострочного ввода? Ваш единственный ввод - одна строка, и, например, slsвернет ('','Vroom!','').
AdmBorkBork
это не законченное решение. Я имею в виду, вы можете попробовать slsвместо этого[regex]::Match
mazzy
@mazzy Может быть, вы должны опубликовать это как отдельное решение.
AdmBorkBork
2

Сетчатка , 21 байт

L$m`^[Vv]r(o*)m!$
$.1

Попробуйте онлайн! Объяснение: Lперечисляет совпадения, поэтому, если регулярное выражение не совпадает, вывод пуст. $результатом является замена, а не совпадение. mделает его многострочным соответствием (эквивалент трейлинга mв вопросе). .В замене делает его выход длина захвата в десятичной системе .

Нил
источник
2

СНОБОЛ4 (CSNOBOL4) , 99 82 байта

I	INPUT POS(0) ('V' | 'v') 'r' ARBNO('o') @X 'm!' RPOS(0)	:F(I)
	OUTPUT =X - 2
END

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

Довольно прямой перевод спецификации SNOBOL, читает каждую строку, пока не найдет ту, которая соответствует ^[Vv]ro*m!$, а затем выводит длину o*бита.

Входит в бесконечный цикл, если не Vroom!может быть найдено.

Giuseppe
источник
Нужен ли весь этот пробел? Вау.
FireCubez
5
@FireCubez Да, это то, что вы получаете с языком старше 50 лет: странные требования к пробелам. Он использует пробел / табуляцию как конкатенацию, и вы должны также окружать операторов пробелами.
Джузеппе
2

C (gcc) , 188 183 байта

Зачем использовать регулярные выражения, если вместо этого вы можете использовать конечный автомат? :-)

a,b;f(char*s){for(a=b=0;a<5;s++){!a&*s==86|*s=='v'?a++:a==1&*s=='r'?a++:a==2?*s-'o'?*s-'m'?0:a++:b++:a==3&*s==33?a++:!*s&a==4?a++:*s-10?(a=-1):a-4?(a=0):a++;if(!*s)break;}s=a<5?-1:b;}

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

ErikF
источник
1

Haskell , 75 71 69 байт

f s=[length n-2|r<-lines s,n<-scanr(:)"m!"$'o'<$r,v<-"Vv",r==v:'r':n]

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

Нет регулярных выражений Вместо этого строит все допустимые Vrooom!строки до достаточной длины и сравнивает строки ввода с ними, собирая количество os в списке. Таким образом, для неверных входных данных возвращается пустой список.

Laikoni
источник
1

C (gcc) , 104 100 байт

s;main(c,n){for(;gets(&s);sscanf(&s,"v%*[o]%nm%c%c",&n,&c,&c)-1||c-33?:printf("%d",n-2))s=s-768|32;}

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

Выведите nдля каждой действительной строки, точно в требовании (ничего, если нет действительной строки, nесли точно одна)

int s; // Use as a char[]
main(c){
  while(gets(&s)) {
    s=s-768|32; // byte 0: 'V'=>'v'; byte 1: 'r'=>'o', 'o'=>'l'
    if (sscanf(&s,"v%[o]m%c%c",&s,&c,&c)==2 && c=='!') {
    // The last '%c' get nothing if it's EndOfLine
      printf("%d",strlen(&s)-1))
    }
  }
}
l4m2
источник
Это так забавно, что ответ регулярного выражения длиннее, чем это
Windmill Cookies
@WindmillCookies GCC нужен дополнительный код для поддержки регулярных выражений
l4m2
хмм. кажется, что имена, связанные с регулярными выражениями, очень длинные
Windmill Cookies
1

Japt , 18 байт

fè`^[Vv]*m!$` ®èo

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

Сохраняет байт, принимая входные данные в виде массива строк.

Включает непечатаемый символ между ]и *.

Объяснение:

fè                   Get the line(s) that match
  `^[Vv]*m!$`          The provided RegEx with a little compression
              ®èo    Count the number of "o" in that line if it exists
Камил Дракари
источник
1
19 байтов
лохматый
На самом деле, поскольку входные данные могут быть массивом строк, вы можете выбить первый байт из моего первого комментария выше.
Лохматый
@ Shaggy Я не могу найти нигде в вопросе, который указывает, что входные данные могут быть массивом строк, и в методах ввода / вывода по умолчанию, по-видимому, не указано, что многострочная строка может быть взята в качестве массива строк. , Вроде бы разумно, но я сначала подожду подтверждения.
Камил Дракари
1

C (gcc) , 138 124 байта

Вот скучный способ регулярных выражений.

#include<regex.h>
f(char*s){regmatch_t m[9];regcomp(m+2,"^[Vv]r(o*)m!$",5);s=regexec(m+2,s,2,m,0)?-1:m[1].rm_eo-m[1].rm_so;}

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

ErikF
источник
0

Pyth, 20 байт

/R\o:#"^Vro*m!$"1cQb

Выводится в виде списка, содержащего только число «о», или пустого списка, если нет Vroom.
Попробуй здесь

объяснение

/R\o:#"^Vro*m!$"1cQb
                 cQb  Split on newlines.
    :#"^Vro*m!$"1     Filter the ones that match the regex.
/R\o                  Count the `o`s in each remaining element.

источник
0

Пип , 21 байт

a~,`^[Vv]r(o*)m!$`#$1

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

Соответствие регулярному выражению ^[Vv]r(o*)m!$в многострочном режиме; выходная длина группы захвата.

DLosc
источник
0

Красный , 104 байта

func[s][n:""if parse/case s[opt[thru"^/"]["V"|"v"]"r"copy n any"o""m!"opt["^/"to end]][print length? n]]

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

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

Red []
f: func [ s ] [
    n: ""
    if parse/case s [
             opt [ thru newline ]
             [ "V" | "v" ]
             "r"
             copy n any "o"
             "m!"
             opt [ newline to end ]
    ] [ print length? n ]
]
Гален Иванов
источник
0

J 35 байт

(]{~0<{.)(1{'^[Vv]r(o*)m!'rxmatch])

Возвращает отрицательное значение 1, если шаблон не совпадает.

hoosierEE
источник
0

JavaScript, 90 73 61 байт

_=>_.replace(/^[Vv]r(o*)m!$|[^\1]/mg,(m,a)=>a||'').length||-1

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

Замените символы, которые не были захвачены, (o*)пустой строкой, возвращением lengthстроки, содержащей только, "o"или -1если результирующая строка пуста.

guest271314
источник
0

Рубин, 32 байта

->n{n=~/^[Vv]r(o*)m!$/m;$1.size}

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

Назовите это так:

x=->n{n=~/^[Vv]r(o*)m!$/m;$1.size}
x["Vrooooooooooooooooooooom!"] # returns 21
NO_BOOT_DEVICE
источник
0

Рубин , 28 29 байт

p$_[/^[vV]r(o*)m!$/].count ?o

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

Многострочные строки требуют еще три байта. Я не уверен, что это жесткое требование. Если так, я обновлю это.

->l{l[/^[Vv]r(o*)m!$/].count ?o}
canhascodez
источник
Как вы можете проверить многострочные строки?
Лайкони
1
Fail onVROM!
l4m2
0

Clojure , 90 байт

#(do(def a(clojure.string/replace % #"(?ms).*^[Vv]r(o*)m!$.*""$1"))(if(= a %)-1(count a)))

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

Эта анонимная функция возвращает число «o» в строке vroom или -1, если нет допустимой строки vroom.

Читаемая версия

(fn [s]
  (def a (clojure.string/replace s #"(?ms).*^[Vv]r(o*)m!$.*" "$1"))
  (if (= a s) -1 (count a)))

объяснение

#"(?ms).*^[Vv]r(o*)m!$.*" ; This regex matches any string that contains a valid vroom string. The first capturing group contains only the "o"s in the vroom string
(clojure.string/replace s #"(?ms).*^[Vv]r(o*)m!$.*" "$1") ; Replaces a match of the above regex with its first capturing group. The resulting string is stored in the variable a
(if (= a s) -1 (count a))) ; a equals s if and only if there is no valid vroom string, so if a equal s we return -1. If there is a valid vroom string, a contains only the "o"s from the vroom string, so we return the length of a
TheGreatGeek
источник
0

perl -nE, 35 байт

$s=length$1if/^[Vv]r(o*)m!$/}{say$s

При этом используется эскимос приветствия ( }{), который неправильно описывает, как -nопция обрабатывается в Perl.


источник
0

Java 8, 109 байт

s->{int r=-1;for(var l:s.split("\n"))r=l.matches("[Vv]ro*m\\!")?l.replaceAll("[^o]","").length():r;return r;}

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

Объяснение:

s->{                             // Method with String parameter and integer return-type
  int r=-1;                      //  Result-integer, starting at -1
  for(var l:s.split("\n"))       //  Loop over the lines:
    r=l.matches("[Vv]ro*m\\!")?  //   If the current line matches the regex:
       l.replaceAll("[^o]","").length()
                                 //    Change `r` to the amount of "o"'s in it
      :                          //   Else:
       r;                        //    Leave the result `r` unchanged
  return r;}                     //  Return the result
Кевин Круйссен
источник
0

C # (.NET Core) , 134 122 байта

for(var a="";a!=null;a=Console.ReadLine())if(new Regex(@"^[Vv]ro*m!$").Match(a).Success)Console.Write(a.Count(x=>x=='o'));

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

-12 байт: перенесены null проверки в for цикл и удалены скобки

Ungolfed:

for(var a = ""; a != null; a = Console.ReadLine())  // initialize a, and while a isn't null, set to new line from console
    if(new Regex(@"^[Vv]ro*m!$")                        // set regex
                        .Match(a).Success)              // check if the line from the console matches
        Console.Write(a.Count(x => x == 'o'));              // write the number of 'o's to the console
Meerkat
источник
-10 байт с ноль-объединяющими и условными операторами C # 6 , также ненужными {}при использовании только одного оператора в forцикле:for(var a="";;a=Console.ReadLine())Console.WriteLine(new Regex(@"^[Vv]ro*m!$").Match(a??"").Success?a.Count(x =>x=='o'):-1);
Ivan García Topete
Кроме того, это необходимо using System.Linq; using System.Text.RegularExpressions;, не уверен, если это важно, LOL
Иван Гарсия Topete
Код, который вы предоставили, на самом деле не работает, так как он будет не только выводить a -1для каждой строки, с которой он не работает, но он будет выводить -1s всегда, так как нет проверки null.
Сурикат
Нет не будет a = Console.ReadLine()делает цикл, поэтому каждый раз, когда вы запрашиваете ввод для продолжения цикла, если нет ввода, цикл просто ждет, а не печатает -1вечно
Ivan García Topete
Доказательство концепции. Даже если это сработало, как вы сказали, бесконечный цикл - не идеальное поведение. Несмотря на это, я перенес нулевую проверку в цикл for, который удаляет скобки (и делает код короче, чем вы предлагаете).
Сурикат
0

05AB1E , 39 37 байт

|ʒć„VvsåsÁÁD…m!rÅ?s¦¦¦Ù'oså)P}Dgi`'o¢

Хотя 05AB1E является языком игры в гольф, проблемы, связанные с регулярными выражениями, определенно не являются его сильной стороной, поскольку в нем нет встроенных регулярных выражений.

Выводится, []если совпадений не найдено.

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

Объяснение:

|              # Get the input split by newlines
 ʒ             # Filter it by:
  ć            #  Head extracted: Pop and push the remainder and head-character
               #   i.e. "vrm!" → "rm!" and "v"
               #   i.e. "Vroaom!" → "roaom!" and "V"
   Vvså       #  Is this head character in the string "Vv"?
               #   i.e. "v" → 1 (truthy)
               #   i.e. "V" → 1 (truthy)
  s            #  Swap so the remainder is at the top of the stack again
   ÁÁ          #  Rotate it twice to the right
               #   i.e. "rm!" → "m!r"
               #   i.e. "roaom!" → "m!roao"
     D         #  Duplicate it
      m!rÅ?   #  Does the rotated remainder start with "m!r"?
               #   i.e. "m!r" → 1 (truthy)
               #   i.e. "m!roao" → 1 (truthy)
  s¦¦¦         #  Remove the first three characters from the duplicated rotated remainder
               #   i.e. "m!r" → ""
               #   i.e. "m!roao" → "oao"
      Ù        #  Uniquify, leaving only distinct characters
               #   i.e. "" → ""
               #   i.e. "oao" → "oa"
       'oså   '#  Is this uniquified string in the string "o"?
               #   i.e. "" → 1 (truthy)
               #   i.e. "oa" → 0 (falsey)
  )P           #  Check if all three checks above are truthy
               #   i.e. [1,1,1] → 1 (truthy)
               #   i.e. [1,1,0] → 0 (falsey)
 }             # Close the filter
  D            # After the filter, duplicate the list
   gi          # If its length is 1:
               #   i.e. ["vrm!"] → 1 (truthy)
               #   i.e. [] → 0 (falsey)
     `         #  Push the value in this list to the stack
               #   i.e. ["vrm!"] → "vrm!"
      'o¢     '#  And count the amount of "o" in it (and output implicitly)
               #   i.e. "vrm!" → 0
               # (Implicit else:)
               #  (Implicitly output the duplicated empty list)
               #   i.e. []
Кевин Круйссен
источник
0

C ++, MSVC, 164 159 байт

-5 байт благодаря Захари

Компилируется даже с regexзаголовком

#include<regex>
using namespace std;int f(vector<string>i){smatch m;for(auto&e:i)if(regex_match(e,m,regex("^[Vv]ro*m!$")))return m[0].str().size()-4;return-1;}

Тесты:

std::cout << "Vrom!" << " -> " << f({ "Vrom!" }) << '\n';
std::cout << "vrooooooom!" << " -> " << f({ "vrooooooom!" }) << '\n';
std::cout << "Hello, Vroom!" << " -> " << f({ "Hello, Vroom!" }) << '\n';
std::cout << "Foo bar boo baz \\n Vrooom! \\n hi" << " -> " << f({ "Foo bar boo baz", "Vrooom!", "hi" }) << '\n';
std::cout << "Vrm!ooo" << " -> " << f({ "Vrm!ooo" }) << '\n';
std::cout << "PPCG puzzlers pie" << " -> " << f({ "PPCG puzzlers pie" }) << '\n';
std::cout << "hallo \\n vROOOm!" << " -> " << f({ "hallo", "vROOOm!" }) << '\n';
HatsuPointerKun
источник
1
Я думаю, using namespace std;что сэкономит несколько байтов
Zacharý