IPv4アドレスの欠落している期間を修正する


37

IPv4アドレスを入力するときに、すべての数字を正しく入力することもありますが、1つ以上のピリオドを入力するのを忘れています。壊れたIPv4アドレスを取得し、欠落しているピリオドのすべての有効な配置を出力するプログラム(または機能)が必要です。

入力

入力は常に、有効なIPv4アドレスの変換である文字列になります(以下の詳細を参照)。常に1つ以上のピリオド文字を削除するだけで変換されます。

送信する際に、この形式以外の入力を処理する必要はありません。

出力

ピリオド文字を入力に挿入することで入力から作成できるすべての有効なIPv4アドレスを表す文字列のコレクションまたはリスト。特定の順序や形式はありません。

  • 出力は、言語固有のリスト、またはその他の順序付けされたまたは順序付けされていないコレクションタイプです。
  • または、何らかの明確な方法で区切られたIPv4アドレスの文字列シーケンスである場合もあります。
    • 1文字の区切り文字を使用して文字列を区切る場合、その1文字の区切り文字としてピリオドと数字は使用できません。数字とは異なり、区切り文字としてのピリオドはあいまいではありません(4番目ごとにピリオドが必ず区切り文字になるため)が、読みやすくするために、これを禁止しています。

IPv4アドレス形式

IPv4アドレスは実際には4つのバイナリオクテットのシーケンスにすぎませんが、このチャレンジでは制限付きドット付き10進形式を使用します。

  • IPv4アドレスは、3つのピリオドで区切られた4つの10進数値です。
  • 4つの値はそれぞれ、0からまでの範囲に255あります。
  • 数値の先頭にゼロを使用することはできません。(スタンドアロン一文字が0許可され、ゼロから始まる任意の他の数ではない:05200、等)

テストケース

入力は1行目に、出力は2行目にあります(ここでは、引用符で囲まれたコンマ区切りのリストとして構成され、コンマで区切られ、で囲まれて[ ]いますが、上記のように、適切な形式または構造を使用できます)。一部の例では、特定のルールの適用を強調するために3行目に注記があります。

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」は正しいソリューションを1つだけ返すはずです... 0.0.0.125?
キータ

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 GiBのRAMが必要です。

使い方

       ,             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.219.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アドレスの余分なドットをスキップして(メインの比較アドレスではない)カスタム比較を実行して、印刷するかどうかを決定します。非常に遅いが、妥当なPCで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

編集:@apsillersのおかげで6バイトを節約しました。@YOUの有効性テストをコピーして、さらに6バイトを保存しました。


[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アドレスが有効な場合に印刷します。(ab)usingによってIPアドレスの有効性をチェックし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ソリューションを次に示します。2番目と3番目のインデントレベルは、それぞれ\t(rawタブ)と\t (rawタブとスペース)です。これはMarkdownで非常に悪い結果をもたらすため、タブは2つのスペースに置き換えられました。

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アドレスを新しい行に出力します。

@grawityのおかげで9バイト節約されました!


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句の周りに括弧が必要かどうか疑問に思いましたか?
ニール

@Neil、ありがとう、それらは必要ありませんでした。
あなたは
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.