Виправте пропущені періоди моєї 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"]

(Я зробив ці приклади вручну, тому, будь ласка, попередити мене про будь-які помилки, які ви можете знайти.)


порядок виводу - це питання?
ВИ

@YOU Ні: " Колекція чи список, не в конкретному порядку чи форматі ... "
apsillers

Провідні нулі заборонені : чи це стосується і вводу?
Луїс Мендо

3
Отже .... "000125" повинен повернути лише одне правильне рішення ... 0.0.0.125?
Keeta

2
@Keeta Це абсолютно правильно. (Я щойно додав це як тестовий випадок.)
apsillers

Відповіді:


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 Правильно.
Anders Kaseorg

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 години на розумному ПК .


Ви можете видалити i=0;.
betseg

@ReleasingHeliumNuclei Я думав, що не можу (функцію потрібно повторно використовувати), але тепер я розумію, що після функції iзнову 0
orlp

6

Perl 5, 91 байт

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

Програма очікує єдиного рядка з одного входу і виводить список кандидатів з обмеженим простором.

Пояснення

Програма використовує функцію зворотного відстеження регулярного виразу, щоб переглядати всі можливості формування дійсної 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

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

Пітон 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 + ручна перевірка?
grawity


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пункту?
Ніл

@Neil, дякую, вони не потребували.
ВИ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.