Исправьте пропущенные периоды моего IPv4-адреса

37

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

вход

Входными данными всегда будет строка, представляющая собой преобразование действительного адреса IPv4 (подробности см. Ниже). Он всегда будет преобразован исключительно путем удаления одного или нескольких символов периода.

Ваша заявка не должна обрабатывать ввод за пределами этого формата.

Выход

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

  • Вывод может быть списком родного языка или другим упорядоченным или неупорядоченным типом коллекции.
  • В качестве альтернативы, это может быть последовательность строк адреса IPv4, определенная каким-либо четким образом.
    • Если вы используете для разделения строки односимвольный разделитель, точки и цифры не допускаются в качестве этого разделителя. Я понимаю, что, в отличие от чисел, периоды в качестве разделителей не являются неоднозначными (поскольку каждый четвертый период обязательно будет разделителем), но для удобства чтения я запрещаю это.

Формат адреса IPv4

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

  • Адрес IPv4 - это четыре десятичных значения, разделенных тремя периодами.
  • Каждое из четырех значений находится в диапазоне 0до 255включительно.
  • Ведущие нули не допускаются ни при каких числовых значениях. (Изолированный из одного символа 0допускаются; любое другое число , начиная с нулем не является: 052, 00и т.д.)

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

Входные данные находятся в первой строке, выходные - во второй строке (здесь, структурированный как разделенный запятыми список строк в кавычках, разделенных запятыми, окруженный [ ], но вы можете использовать любой разумный формат или структуру, как указано выше). Некоторые примеры имеют примечания в третьей строке, чтобы выделить применение определенного правила.

192.168.1234
["192.168.1.234", "192.168.12.34", "192.168.123.4"]

192.1681234
["192.16.81.234", "192.168.1.234", "192.168.12.34", "192.168.123.4"]
(Note: 192.1681.2.34 (etc.) is illegal because 1681 is greater than 255)

1921681.234
["19.216.81.234", "192.16.81.234", "192.168.1.234"]

1921681234
["19.216.81.234", "192.16.81.234", "192.168.1.234", "192.168.12.34", "192.168.123.4"]

192.168.1204
["192.168.1.204", "192.168.120.4"]
(Note: 192.168.12.04 is illegal because of leading zero)

192.168.123
["1.92.168.123", "19.2.168.123", "192.1.68.123", "192.16.8.123", "192.168.1.23", "192.168.12.3"]

192.168.256
["192.168.2.56", "192.168.25.6"]
(Note: Any combination that would leave 256 intact is illegal)

120345
["1.20.3.45", "1.20.34.5", "1.203.4.5", "12.0.3.45", "12.0.34.5", "120.3.4.5"]
(Note: 12.03.4.5 (etc.) is illegal due to leading zero.)

012345
["0.1.23.45", "0.1.234.5", "0.12.3.45", "0.12.34.5", "0.123.4.5"]
(Note: the first segment must be 0, because `01` or `012` would be illegal.)

000123
["0.0.0.123"]

(Я сделал эти примеры вручную, поэтому, пожалуйста, предупредите меня о любых ошибках, которые вы можете найти.)

apsillers
источник
порядок вывода имеет значение?
ВЫ
@YOU Нет: « Коллекция или список, без определенного порядка или формата ... »
apsillers
Ведущие нули не допускаются : это относится и к вводу?
Луис Мендо
3
Итак ... "000125" должен возвращать только одно правильное решение ... 0.0.0.125?
Кита
2
@Keeta Это точно правильно. (Я только добавил его в качестве тестового примера.)
Апсиллер

Ответы:

9

Pyth, 24 байта

f&q4lJcT\.!-J`M256jL\../

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

Как это работает

                      ./Q   all partitions of input
                  jL\.      join each on .
f                           filter for results T such that:
      cT\.                    split T on .
     J                        assign to J
    l                         length
  q4                          equals 4
 &                            … and:
           -J`M256              J minus the list of representations of [0, …, 255]
          !                     is false (empty)

Pyth, 17 байт, очень медленный

@FjLL\.,^U256 4./

Предупреждение. Не беги. Требуется около 553 ГБ ОЗУ.

Как это работает

       ,             two-element list of:
        ^U256 4        all four-element lists of [0, …, 255]
               ./Q     all partitions of input
  jLL\.              join each element of both on .
@F                   fold intersection
Андерс Касеорг
источник
Ницца! Просто для моего понимания, «все разделы ввода» означают все возможные способы сегментации ввода, верно? Таким образом, вы делаете каждое возможное разделение, а затем присоединяетесь к разделениям с периодами, чтобы в итоге вы получили множество кандидатов, таких как 1.9.2.1.6.8.1.2и 19.2.1.6.8.1.2т. Д. (Но тогда, очевидно, все недействительные отфильтровываются)
apsillers
@apsillers Правильно.
Андерс Касеорг
16

C (gcc / linux), 125 121 байт

i;f(char*a){do{char*y=a,s[99],*x=inet_ntop(2,&i,s,99);for(;*x&&!(*x^*y&&*x^46);++x)y+=*x==*y;*x|*y||puts(s);}while(++i);}

Перебирает все возможные адреса IPv4 и выполняет пользовательское сравнение, которое пропускает лишние точки в сгенерированном IP-адресе (но не в основном адресе сравнения), чтобы решить, печатать или нет. Очень медленно, но должно закончиться в течение 1 часа на разумном ПК .

orlp
источник
Вы можете удалить i=0;.
Betseg
@ReleasingHeliumNuclei Я думал, что не смогу (функция должна использоваться повторно), но теперь я понимаю, что после того, как функция iснова
станет равной
6

Perl 5, 91 байт

<>=~/^(([1-9]?|1\d|2[0-4])\d|25[0-5])\.?((?1))\.?((?1))\.?((?1))$(?{print"$1.$3.$4.$5 "})^/

Программа ожидает одну строку одного ввода и выводит разделенный пробелами список кандидатов.

объяснение

Программа использует функцию обратного отслеживания в regex для обхода всех возможностей формирования действительного IPv4-адреса из входной строки.

^(([1-9]?|1\d|2[0-4])\d|25[0-5])\.?((?1))\.?((?1))\.?((?1))$

Регулярное выражение IPv4 с необязательным ., ничего особенного здесь нет.

(?{print"$1.$3.$4.$5 "})

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

^

Сделать матч не удастся и заставить отступить.

Пример запуска

$ echo "012345" | perl G89503.pl
0.12.34.5 0.12.3.45 0.1.23.45 0.1.234.5 0.123.4.5
n̴̖̋h̷͉a̷̭̿h̸̡̅ẗ̵̨d̷̰ĥ̷̳
источник
5

JavaScript (ES6), 147 141 135 байт

f=(s,n=0)=>(a=s.split`.`)[3]?a.every(s=>s==`0`|s[0]>0&s<256)?s+' ':'':[...s].map((_,i)=>i>n?f(s.slice(0,i)+`.`+s.slice(i),i):``).join``
<input placeholder=Input oninput=o.textContent=f(this.value)><div id=o style=font-family:monospace;width:1em>Output

Редактировать: сохранено 6 байтов благодаря @apsillers. Сохраните еще 6 байтов, скопировав тест достоверности @ YOU.

Нил
источник
Есть ли разница между [1-9] | 0 и [0-9] или \ d ??
ВЫ
@apsillers Ах да, более ранняя версия моего кода могла генерировать трейлинг . который бросил бы тест, но я думаю, что эта версия в порядке.
Нил
@YOU Важно то, что 0есть $. (Это также не хватает ^, так что спасибо, что обратили на это мое внимание.)
Нил
К сожалению, @apsillers spliceне работает так, он изменяет массив и возвращает все удаленные элементы.
Нил
4

Python 3, 232 байта

import re,itertools as t,ipaddress as k
R=range
i=input()
for d in R(5):
 for p in t.combinations(R(len(i)),d):
  n=i;o=0
  for a in p:n=n[:a+o]+'.'+n[a+o:];o+=1
  try:k.ip_address(n);print(n*(not re.search(r'\D?0\d',n)))
  except:0

Довольно просто: мы размещаем периоды везде и печатаем, если IP-адрес с установленными периодами действителен. Мы проверяем действительность IP-адресов с помощью (ab) ipaddress.ip_address, что вызывает исключение, если ввод не является действительным IP-адресом. Задача определяет некоторые дополнительные правила, которые ip_addressне обрабатываются (а именно, что не может быть начальных нулей), поэтому мы проверяем их также с помощью регулярного выражения, а затем печатаем.

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

Пример выполнения:

$ echo 012345 | python fixip.py
0.1.23.45
0.1.234.5
0.12.3.45
0.12.34.5
0.123.4.5





$ echo 000123 | python fixip.py
0.0.0.123








_

Вот мое старое 248-байтовое решение Python 2. Второй и третий уровни отступа \t(необработанная вкладка) и \t (необработанная вкладка плюс пробел) соответственно. Это играет очень плохо с Markdown, так что выступы были заменены двумя пробелами.

import socket,re,itertools as t
R=range
i=input()
for d in R(5):
 for p in t.combinations(R(len(i)),d):
  n=i;o=0
  for a in p:n=n[:a+o]+'.'+n[a+o:];o+=1
  try:
   socket.inet_aton(n)
   if n.count('.')==3and not re.search(r'\D?0\d',n):print n
  except:0

Требуется ввод, заключенный в кавычки (например, "123.456.789" ). Выводит каждый сгенерированный IP-адрес на новую строку.

Сохранено 9 байтов благодаря @grawity!

медь
источник
1
Будет ipaddress.ip_address()короче чем aton + ручная проверка?
Гравитация
2

Python 3, 262 260 байт

p,l,L,T=set(),-1,len,tuple
while l<L(p):l=L(p);p|={T(z[:i]+(y[:j],y[j:])+z[i+1:])for z in set(p)or[T(input().split("."))]for i,y in enumerate(z)for j in range(1,L(y))}
print(['.'.join(x)for x in p if L(x)==4and all(y=='0'or y[0]!='0'and int(y)<256for y in x)])

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

Результаты все равно.

for x in 192.168.1234 192.1681234 1921681.234 1921681234 192.168.1204 192.168.123 192.168.256 120345 012345 000123; do
echo $x | python3 ipv4.py
done;

['192.168.123.4', '192.168.1.234', '192.168.12.34']
['192.16.81.234', '192.168.1.234', '192.168.123.4', '192.168.12.34']
['19.216.81.234', '192.168.1.234', '192.16.81.234']
['19.216.81.234', '192.168.123.4', '192.168.12.34', '192.16.81.234', '192.168.1.234']
['192.168.1.204', '192.168.120.4']
['192.16.8.123', '19.2.168.123', '1.92.168.123', '192.168.1.23', '192.168.12.3', '192.1.68.123']
['192.168.25.6', '192.168.2.56']
['1.20.3.45', '1.203.4.5', '12.0.34.5', '120.3.4.5', '1.20.34.5', '12.0.3.45']
['0.1.23.45', '0.12.3.45', '0.12.34.5', '0.123.4.5', '0.1.234.5']
['0.0.0.123']
ТЫ
источник
1
Я подумал, что скопирую ваш тест на достоверность, и подумал, нужны ли вам скобки вокруг этого orпредложения?
Нил
@ Нил, спасибо, они не нужны.
ВЫ