Cracking the Enigma?

66

9

Introduction

The Enigma was one of the first electro-mechanical rotor cipher machines used in World War II. That means that after a single letter is coded, it would change the key for the next letter. This was considered unbreakable by the Germans, due to the enormous key space. Even brute-forcing was almost impossible. However, there was a design error in the Enigma. Encrypting a letter would never result into itself. That means that the letter A can encrypt to every letter except the letter A.

Let's take an example of a coded message:

BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ

A typical German word was WETTERBERICHT, or weather report in English. With the principe above, we can determine at which locations the word could possibly be:

BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ
WETTERBERICHT
         ^

This is not possible, because the I can't be encrypted to itself, so we move on 1 place:

BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ
 WETTERBERICHT
             ^

This is also not possible, so we move another place again:

BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ
  WETTERBERICHT
   ^

This again is not possible. In fact, the first possible occurence of WETTERBERICHT is:

BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ
             WETTERBERICHT
0123456789012345678901234567890123456789012345678901234567890123
             ^
             13

So, we return the 0-indexed position of the first possible occurence, which is 13.

The Task

  • Given a coded message and a word, find the index of the first possible occurence.
  • Assume that only basic uppercase alphabetic characters will be used (ABCDEFGHIJKLMNOPQRSTUVWXYZ).
  • If no occurence is found, you can output any negative integer, character, or nothing (e.g. -1, X).
  • Input may be accepted as argument, on seperate newlines, lists or anything else.
  • This is , so the submission with the least amount of bytes wins!

Test cases

Input: BHGEFXWFTIUPITHHLPETTTCLOEWOELM, WETTERBERICHT
Output: 13

Input: ABCDEFGHIJKL, HELLO
Output: 0

Input: EEEEEEEEEEEE, HELLO
Output: -1

Input: XEEFSLBSELDJMADNADKDPSSPRNEBWIENPF, DEUTSCHLAND
Output: 11

Input: HKKH, JJJJJ
Output: -1

Adnan

Posted 2015-12-30T15:17:02.120

Reputation: 41 965

1Umm, why does the encoded string change in the middle of the example? – Doorknob – 2015-12-30T15:56:49.193

37@Doorknob冰 ¯\(ツ) – Adnan – 2015-12-30T15:59:06.443

There are issues with the introduction:

  1. it wasn't considered unbreakable because of the key space, but because of the system that a letter changes what it is translated to
  2. "Encrypting a letter would never result into itself." - yes it would, after the number of available characters it would have to repeat one.
  3. < – Zelphir Kaltstahl – 2016-01-01T13:38:29.760

3@Zelphir with encrypting to itself, I meant that the E would never result into an E. That is what this whole challenge is about. – Adnan – 2016-01-01T16:22:45.720

Answers

9

Pyth, 14 bytes

f!s.eqb@>zTkQ0

I'm not sure if this is Ok but if the input is impossible, nothing is written to stdout and a zero division error is written to stderr. Takes the input on 2 lines, the second one is surrounded by quotes.

Explanation:

               - autoassign z to first input
               - autoassign Q to second input
f            0 - The first value starting from 0 where the output is truthy
   .e       Q  - Enumerate over the second value
        >zT    - z[T:]
       @   k   - The kth item (number in enumeration)
      b        - The character in the enumeration
     q         - Are the two characters equal?
  s            - Sum the values
 !             - Invert them (want first where there isn't a collision)

Try it here!

Blue

Posted 2015-12-30T15:17:02.120

Reputation: 26 661

55

JavaScript, 40

(c,p)=>c.search(p.replace(/./g,"[^$&]"))

Using replace, this maps the plaintext input into a regular expression of form /[^H][^E][^L][^L][^O]/ (e.g., for plaintext input HELLO) and then uses search to test for the first index of the ciphertext substring that matches that regex. This regex means "a pattern where the first character is not H, the second character is not E, etc."

$& is a special sequence for replace output that substitutes in the value matched by the first replace argument (in this case, each single character matched by /./).

apsillers

Posted 2015-12-30T15:17:02.120

Reputation: 3 632

16Oh, wow, that's a really clever solution! – Doorknob – 2015-12-30T16:07:54.013

2I didn't know about $&! Thanks for teaching my something today. – ETHproductions – 2015-12-30T16:19:42.837

1

@ETHproductions Me neither, until today! I also learned about $and$'` in the process of researching this answer, which provide "the portion of the string that precedes/follows the matched substring"

– apsillers – 2015-12-30T16:22:04.783

1Wow, that's awesome! I should read the docs more often ;) – ETHproductions – 2015-12-30T16:24:11.687

44

Turing Machine Simulator - 15660 bytes (Non-Competing)

Can't have an Enigma challenge without turing machine code.

0 * * l 0
0 _ _ l ,
, _ , l 1
1 _ 0 r 2
2 * * r 2
2 , * r 3
3 * * r 3
3 , * r 4
4 * * r 4
4 _ * r 13
4 A a l a'                                                                                                                                                                                                        
4 B b l b'                                                                                                                                                                                                        
4 C c l c'                                                                                                                                                                                                        
4 D d l d'                                                                                                                                                                                                        
4 E e l e'                                                                                                                                                                                                        
4 F f l f'                                                                                                                                                                                                        
4 G g l g'                                                                                                                                                                                                        
4 H h l h'                                                                                                                                                                                                        
4 I i l i'                                                                                                                                                                                                        
4 J j l j'                                                                                                                                                                                                        
4 K k l k'                                                                                                                                                                                                        
4 L l l l'                                                                                                                                                                                                        
4 M m l m'                                                                                                                                                                                                        
4 N n l n'                                                                                                                                                                                                        
4 O o l o'                                                                                                                                                                                                        
4 P p l p'                                                                                                                                                                                                        
4 Q q l q'                                                                                                                                                                                                        
4 R r l r'                                                                                                                                                                                                        
4 S s l s'                                                                                                                                                                                                        
4 T t l t'                                                                                                                                                                                                        
4 U u l u'                                                                                                                                                                                                        
4 V v l v'                                                                                                                                                                                                        
4 W w l w'                                                                                                                                                                                                        
4 X x l x'                                                                                                                                                                                                        
4 Y y l y'                                                                                                                                                                                                        
4 Z z l z'
a' * * l a'
a' , * l a
b' * * l b'
b' , * l b
c' * * l c'
c' , * l c
d' * * l d'
d' , * l d
e' * * l e'
e' , * l e
f' * * l f'
f' , * l f
g' * * l g'
g' , * l g
h' * * l h'
h' , * l h
i' * * l i'
i' , * l i
j' * * l j'
j' , * l j
k' * * l k'
k' , * l k
l' * * l l'
l' , * l l
m' * * l m'
m' , * l m
n' * * l n'
n' , * l n
o' * * l o'
o' , * l o
p' * * l p'
p' , * l p
q' * * l q'
q' , * l q
r' * * l r'
r' , * l r
s' * * l s'
s' , * l s
t' * * l t'
t' , * l t
u' * * l u'
u' , * l u
v' * * l v'
v' , * l v
w' * * l w'
w' , * l w
x' * * l x'
x' , * l x
y' * * l y'
y' , * l y
z' * * l z'
z' , * l z

a * * l a
a _ * r A
a a * r A
a b * r A
a c * r A
a d * r A
a e * r A
a f * r A
a g * r A
a h * r A
a i * r A
a j * r A
a k * r A
a l * r A
a m * r A
a n * r A
a o * r A
a p * r A
a q * r A
a r * r A
a s * r A
a t * r A
a u * r A
a v * r A
a w * r A
a x * r A
a y * r A
a z * r A
b * * l b
b _ * r B
b a * r B
b b * r B
b c * r B
b d * r B
b e * r B
b f * r B
b g * r B
b h * r B
b i * r B
b j * r B
b k * r B
b l * r B
b m * r B
b n * r B
b o * r B
b p * r B
b q * r B
b r * r B
b s * r B
b t * r B
b u * r B
b v * r B
b w * r B
b x * r B
b y * r B
b z * r B
c * * l c
c _ * r C
c a * r C
c b * r C
c c * r C
c d * r C
c e * r C
c f * r C
c g * r C
c h * r C
c i * r C
c j * r C
c k * r C
c l * r C
c m * r C
c n * r C
c o * r C
c p * r C
c q * r C
c r * r C
c s * r C
c t * r C
c u * r C
c v * r C
c w * r C
c x * r C
c y * r C
c z * r C
d * * l d
d _ * r D
d a * r D
d b * r D
d c * r D
d d * r D
d e * r D
d f * r D
d g * r D
d h * r D
d i * r D
d j * r D
d k * r D
d l * r D
d m * r D
d n * r D
d o * r D
d p * r D
d q * r D
d r * r D
d s * r D
d t * r D
d u * r D
d v * r D
d w * r D
d x * r D
d y * r D
d z * r D
e * * l e
e _ * r E
e a * r E
e b * r E
e c * r E
e d * r E
e e * r E
e f * r E
e g * r E
e h * r E
e i * r E
e j * r E
e k * r E
e l * r E
e m * r E
e n * r E
e o * r E
e p * r E
e q * r E
e r * r E
e s * r E
e t * r E
e u * r E
e v * r E
e w * r E
e x * r E
e y * r E
e z * r E
f * * l f
f _ * r F
f a * r F
f b * r F
f c * r F
f d * r F
f e * r F
f f * r F
f g * r F
f h * r F
f i * r F
f j * r F
f k * r F
f l * r F
f m * r F
f n * r F
f o * r F
f p * r F
f q * r F
f r * r F
f s * r F
f t * r F
f u * r F
f v * r F
f w * r F
f x * r F
f y * r F
f z * r F
g * * l g
g _ * r G
g a * r G
g b * r G
g c * r G
g d * r G
g e * r G
g f * r G
g g * r G
g h * r G
g i * r G
g j * r G
g k * r G
g l * r G
g m * r G
g n * r G
g o * r G
g p * r G
g q * r G
g r * r G
g s * r G
g t * r G
g u * r G
g v * r G
g w * r G
g x * r G
g y * r G
g z * r G
h * * l h
h _ * r H
h a * r H
h b * r H
h c * r H
h d * r H
h e * r H
h f * r H
h g * r H
h h * r H
h i * r H
h j * r H
h k * r H
h l * r H
h m * r H
h n * r H
h o * r H
h p * r H
h q * r H
h r * r H
h s * r H
h t * r H
h u * r H
h v * r H
h w * r H
h x * r H
h y * r H
h z * r H
i * * l i
i _ * r I
i a * r I
i b * r I
i c * r I
i d * r I
i e * r I
i f * r I
i g * r I
i h * r I
i i * r I
i j * r I
i k * r I
i l * r I
i m * r I
i n * r I
i o * r I
i p * r I
i q * r I
i r * r I
i s * r I
i t * r I
i u * r I
i v * r I
i w * r I
i x * r I
i y * r I
i z * r I
j * * l j
j _ * r J
j a * r J
j b * r J
j c * r J
j d * r J
j e * r J
j f * r J
j g * r J
j h * r J
j i * r J
j j * r J
j k * r J
j l * r J
j m * r J
j n * r J
j o * r J
j p * r J
j q * r J
j r * r J
j s * r J
j t * r J
j u * r J
j v * r J
j w * r J
j x * r J
j y * r J
j z * r J
k * * l k
k _ * r K
k a * r K
k b * r K
k c * r K
k d * r K
k e * r K
k f * r K
k g * r K
k h * r K
k i * r K
k j * r K
k k * r K
k l * r K
k m * r K
k n * r K
k o * r K
k p * r K
k q * r K
k r * r K
k s * r K
k t * r K
k u * r K
k v * r K
k w * r K
k x * r K
k y * r K
k z * r K
l * * l l
l _ * r L
l a * r L
l b * r L
l c * r L
l d * r L
l e * r L
l f * r L
l g * r L
l h * r L
l i * r L
l j * r L
l k * r L
l l * r L
l m * r L
l n * r L
l o * r L
l p * r L
l q * r L
l r * r L
l s * r L
l t * r L
l u * r L
l v * r L
l w * r L
l x * r L
l y * r L
l z * r L
m * * l m
m _ * r M
m a * r M
m b * r M
m c * r M
m d * r M
m e * r M
m f * r M
m g * r M
m h * r M
m i * r M
m j * r M
m k * r M
m l * r M
m m * r M
m n * r M
m o * r M
m p * r M
m q * r M
m r * r M
m s * r M
m t * r M
m u * r M
m v * r M
m w * r M
m x * r M
m y * r M
m z * r M
n * * l n
n _ * r N
n a * r N
n b * r N
n c * r N
n d * r N
n e * r N
n f * r N
n g * r N
n h * r N
n i * r N
n j * r N
n k * r N
n l * r N
n m * r N
n n * r N
n o * r N
n p * r N
n q * r N
n r * r N
n s * r N
n t * r N
n u * r N
n v * r N
n w * r N
n x * r N
n y * r N
n z * r N
o * * l o
o _ * r O
o a * r O
o b * r O
o c * r O
o d * r O
o e * r O
o f * r O
o g * r O
o h * r O
o i * r O
o j * r O
o k * r O
o l * r O
o m * r O
o n * r O
o o * r O
o p * r O
o q * r O
o r * r O
o s * r O
o t * r O
o u * r O
o v * r O
o w * r O
o x * r O
o y * r O
o z * r O
p * * l p
p _ * r P
p a * r P
p b * r P
p c * r P
p d * r P
p e * r P
p f * r P
p g * r P
p h * r P
p i * r P
p j * r P
p k * r P
p l * r P
p m * r P
p n * r P
p o * r P
p p * r P
p q * r P
p r * r P
p s * r P
p t * r P
p u * r P
p v * r P
p w * r P
p x * r P
p y * r P
p z * r P
q * * l q
q _ * r Q
q a * r Q
q b * r Q
q c * r Q
q d * r Q
q e * r Q
q f * r Q
q g * r Q
q h * r Q
q i * r Q
q j * r Q
q k * r Q
q l * r Q
q m * r Q
q n * r Q
q o * r Q
q p * r Q
q q * r Q
q r * r Q
q s * r Q
q t * r Q
q u * r Q
q v * r Q
q w * r Q
q x * r Q
q y * r Q
q z * r Q
r * * l r
r _ * r R
r a * r R
r b * r R
r c * r R
r d * r R
r e * r R
r f * r R
r g * r R
r h * r R
r i * r R
r j * r R
r k * r R
r l * r R
r m * r R
r n * r R
r o * r R
r p * r R
r q * r R
r r * r R
r s * r R
r t * r R
r u * r R
r v * r R
r w * r R
r x * r R
r y * r R
r z * r R
s * * l s
s _ * r S
s a * r S
s b * r S
s c * r S
s d * r S
s e * r S
s f * r S
s g * r S
s h * r S
s i * r S
s j * r S
s k * r S
s l * r S
s m * r S
s n * r S
s o * r S
s p * r S
s q * r S
s r * r S
s s * r S
s t * r S
s u * r S
s v * r S
s w * r S
s x * r S
s y * r S
s z * r S
t * * l t
t _ * r T
t a * r T
t b * r T
t c * r T
t d * r T
t e * r T
t f * r T
t g * r T
t h * r T
t i * r T
t j * r T
t k * r T
t l * r T
t m * r T
t n * r T
t o * r T
t p * r T
t q * r T
t r * r T
t s * r T
t t * r T
t u * r T
t v * r T
t w * r T
t x * r T
t y * r T
t z * r T
u * * l u
u _ * r U
u a * r U
u b * r U
u c * r U
u d * r U
u e * r U
u f * r U
u g * r U
u h * r U
u i * r U
u j * r U
u k * r U
u l * r U
u m * r U
u n * r U
u o * r U
u p * r U
u q * r U
u r * r U
u s * r U
u t * r U
u u * r U
u v * r U
u w * r U
u x * r U
u y * r U
u z * r U
v * * l v
v _ * r V
v a * r V
v b * r V
v c * r V
v d * r V
v e * r V
v f * r V
v g * r V
v h * r V
v i * r V
v j * r V
v k * r V
v l * r V
v m * r V
v n * r V
v o * r V
v p * r V
v q * r V
v r * r V
v s * r V
v t * r V
v u * r V
v v * r V
v w * r V
v x * r V
v y * r V
v z * r V
w * * l w
w _ * r W
w a * r W
w b * r W
w c * r W
w d * r W
w e * r W
w f * r W
w g * r W
w h * r W
w i * r W
w j * r W
w k * r W
w l * r W
w m * r W
w n * r W
w o * r W
w p * r W
w q * r W
w r * r W
w s * r W
w t * r W
w u * r W
w v * r W
w w * r W
w x * r W
w y * r W
w z * r W
x * * l x
x _ * r X
x a * r X
x b * r X
x c * r X
x d * r X
x e * r X
x f * r X
x g * r X
x h * r X
x i * r X
x j * r X
x k * r X
x l * r X
x m * r X
x n * r X
x o * r X
x p * r X
x q * r X
x r * r X
x s * r X
x t * r X
x u * r X
x v * r X
x w * r X
x x * r X
x y * r X
x z * r X
y * * l y
y _ * r Y
y a * r Y
y b * r Y
y c * r Y
y d * r Y
y e * r Y
y f * r Y
y g * r Y
y h * r Y
y i * r Y
y j * r Y
y k * r Y
y l * r Y
y m * r Y
y n * r Y
y o * r Y
y p * r Y
y q * r Y
y r * r Y
y s * r Y
y t * r Y
y u * r Y
y v * r Y
y w * r Y
y x * r Y
y y * r Y
y z * r Y
z * * l z
z , * r Z
z a * r Z
z b * r Z
z c * r Z
z d * r Z
z e * r Z
z f * r Z
z g * r Z
z h * r Z
z i * r Z
z j * r Z
z k * r Z
z l * r Z
z m * r Z
z n * r Z
z o * r Z
z p * r Z
z q * r Z
z r * r Z
z s * r Z
z t * r Z
z u * r Z
z v * r Z
z w * r Z
z x * r Z
z y * r Z
z z * r Z
A * * * 5
A A * l 6
B * * * 5
B B * l 6
C * * * 5
C C * l 6
D * * * 5
D D * l 6
E * * * 5
E E * l 6
F * * * 5
F F * l 6
G * * * 5
G G * l 6
H * * * 5
H H * l 6
I * * * 5
I I * l 6
J * * * 5
J J * l 6
K * * * 5
K K * l 6
L * * * 5
L L * l 6
M * * * 5
M M * l 6
N * * * 5
N N * l 6
O * * * 5
O O * l 6
P * * * 5
P P * l 6
Q * * * 5
Q Q * l 6
R * * * 5
R R * l 6
S * * * 5
S S * l 6
T * * * 5
T T * l 6
U * * * 5
U U * l 6
V * * * 5
V V * l 6
W * * * 5
W W * l 6
X * * * 5
X X * l 6
Y * * * 5
Y Y * l 6
Z * * * 5
Z Z * l 6
5 , * r 15
5 A a r 7
5 B b r 7
5 C c r 7
5 D d r 7
5 E e r 7
5 F f r 7
5 G g r 7
5 H h r 7
5 I i r 7
5 J j r 7
5 K k r 7
5 L l r 7
5 M m r 7
5 N n r 7
5 O o r 7
5 P p r 7
5 Q q r 7
5 R r r 7
5 S s r 7
5 T t r 7
5 U u r 7
5 V v r 7
5 W w r 7
5 X x r 7
5 Y y r 7
5 Z z r 7
7 * * r 7
7 , * r 4
6 * * l 6
6 _ * r 8
8 * _ r 9
9 * * r 9
9 _ * l 10
9 a A r 9
9 b B r 9
9 c C r 9
9 d D r 9
9 e E r 9
9 f F r 9
9 g G r 9
9 h H r 9
9 i I r 9
9 j J r 9
9 k K r 9
9 l L r 9
9 m M r 9
9 n N r 9
9 o O r 9
9 p P r 9
9 q Q r 9
9 r R r 9
9 s S r 9
9 t T r 9
9 u U r 9
9 v V r 9
9 w W r 9
9 x X r 9
9 y Y r 9
9 z Z r 9
10 * * l 10
10 , * l 11
11 * * l 11
11 , * l 12
12 _ 1 r 2
12 0 1 r 2
12 1 2 r 2
12 2 3 r 2
12 3 4 r 2
12 4 5 r 2
12 5 6 r 2
12 6 7 r 2
12 7 8 r 2
12 8 9 r 2
12 9 0 l 12
13 * _ l 13
13 , _ l 14
14 * _ l 14
14 , _ l halt
15 * * r 15
15 _ * l 16
16 * _ l 16
16 , _ l 17
17 * _ l 17
17 , _ l 18
18 * _ l 18
18 _ x * halt

Test it out here

Brief overview:

  1. Set up a counter on the left
  2. Find first uppercase letter in target and make it lowercase. If all letters are lowercase move to step 5.
  3. Find first uppercase letter in code. If most recent letter matches, move on to step 4. Else make letter lowercase and go back to step 2.
  4. Increment counter, make all letters capital, delete first letter in code. Go back to step 2. If no letters are left in code, return clear tape and print x.
  5. Clear all the tape but the counter.

KoreanwGlasses

Posted 2015-12-30T15:17:02.120

Reputation: 888

Also, when testing, the format of the input should be: code,target (no space) – KoreanwGlasses – 2015-12-30T21:23:32.700

How long did it take to make this? – Adnan – 2015-12-30T21:24:54.837

18Started my homework at 2:00. Got distracted at 2:15. Started this at 2.20. Posted this at 4:20. So about 2 hours. – KoreanwGlasses – 2015-12-30T21:25:34.423

5+1, in PPCGSE, it doesn't have to be competing to be appreciated! – None – 2016-01-01T20:33:49.963

9575 bytes (and the current bytecount in the header is false, there are extraneous spaces and some unnecessarily long state names). – Erik the Outgolfer – 2018-10-14T11:36:15.440

@EriktheOutgolfer, Your code seems to have a syntax error on line 21. – ouflak – 2019-08-12T08:19:23.160

@ouflak Try clicking "Reset" and then "Run", there's no syntax error. Looks like a false alarm there. – Erik the Outgolfer – 2019-08-12T08:55:29.073

@EriktheOutgolfer, No that code will definitely error. It will run through until it hits that line. Then it will die. Also, lines 57 and 58 will never run (they are commented out with the semicolon). – ouflak – 2019-11-06T12:00:09.140

8

SWI-Prolog, 115 bytes

a(S,W,R):-length(S,L),length(W,M),N is L-M,between(0,N,I),\+ (between(0,M,J),K is I+J,nth0(J,W,A),nth0(K,S,A)),R=I.

Usage example: a(`ABCDEFGHIJKL`,`HELLO`,R).. This uses the character codes strings declared with backticks. The answer is unified with R. If no match is found, this outputs false..

Explanation:

a(S,W,R):-
    length(S,L),length(W,M),     
    N is L-M,
    between(0,N,I),             % I is successively unified with an integer between 0 
                                % and the last possible index of the coded message

    \+ (                        % This will only be true if what's inside the parentheses 
                                % cannot be proven to be true

        between(0,M,J),         % J is successively unified with an integer between 0 
                                % and the length of the desired word
        K is I+J,
        nth0(J,W,A),nth0(K,S,A) % Check if one letter is the same in both string at 
                                % the same index
    ),                          % If it the case, then it will be 'true' and thus 
                                % the predicate \+ will be false, meaning we need to
                                % backtrack to try a different value of I

    R=I.                        % If we get here it means it didn't find any matching 
                                % letter for this value of I, which is then the answer.

Try it here

Fatalize

Posted 2015-12-30T15:17:02.120

Reputation: 32 976

7

CJam, 17 16 bytes

ll:A,ew{A.=:+!}#

Try it here.

Thanks to @PeterTaylor for saving a byte.

Explanation:

ll:A,ew    e# Finds every slice in the coded message with the length of the word
{A.=:+     e# Compare the characters in each slice to the characters in the word, and add up the result. If the sum is zero, then the slice and the word have no characters in common.
!}#        e# Invert truthiness (0 -> 1, non-0 -> 0) Return index of first truthy value.

geokavel

Posted 2015-12-30T15:17:02.120

Reputation: 6 352

array block # can save you a char: ll:A,ew{A.=:+!}# – Peter Taylor – 2015-12-30T18:33:48.913

Amazing how far CJam can be golfed in almost every task... :-o – agtoever – 2015-12-30T19:35:19.427

@agtoever I wouldn't say it's really golfing, because 17 bytes was my very first try. The key feature is ew (make slices), everything else just follows. – geokavel – 2015-12-30T19:41:12.013

7

Ruby, 91 79 bytes

->a,b{[*a.chars.each_cons(b.size)].index{|x|x.zip(b.chars).all?{|y|y.uniq==y}}}

Curse you, Enumerator! Why do I have to convert from string to array to Enumerator to array and waste precious bytes? >:(

->a,b{                  # define lambda
[*                      # convert to array...
  a.chars               # get enumerator from string
  .each_cons(b.size)    # each consecutive group of (b.size) letters
]
.index{|x|              # find index of...
  x.zip(b.chars)        # zip group with second input string
  .all?{|y|             # is the block true for every element?
    y.uniq==y           # uniqueify results in same array (no dups)
}}}

Doorknob

Posted 2015-12-30T15:17:02.120

Reputation: 68 138

Using [*...] as a golfy alternative to #to_a is a nice touch. – Wayne Conrad – 2015-12-30T19:55:11.660

6

MATL, 27 bytes

jYbZ)tnb!wlhYCw!=a~ftn?1)1-

Examples

>> matl jYbZ)tnb!wlhYCw!=a~ftn?1)1-
> EEEEEEEEEEEE, HELLO

>> matl jYbZ)tnb!wlhYCw!=a~ftn?1)1-
> XEEFSLBSELDJMADNADKDPSSPRNEBWIENPF, DEUTSCHLAND
11

Explanation

j           % input string
YbZ)        % split into two strings based on space. Trailing comma is not a problem
tnb!wlhYC   % arrange first string into sliding columns of the size of the second
w!=         % compare with transposed second string, element-wise with broadcast
a~          % detect columns where all values are 0 (meaning unequal characters)
f           % find indices of such columns
tn?         % if there's at least one such column
1)1-        % pick index of the first and subtract 1 for 0-based indexing

Luis Mendo

Posted 2015-12-30T15:17:02.120

Reputation: 87 464

4

Haskell, 72 bytes

l=length
h i w s|l s<l w= -1|and$zipWith(/=)w s=i|1<2=h(i+1)w$tail s
h 0

Usage: h 0 "DEUTSCHLAND" "XEEFSLBSELDJMADNADKDPSSPRNEBWIENPF" -> 11.

Simple recursive approach: if the word wcan be placed at the beginning of the string s, return the index counter i, else repeat with i incremented and the tail of s. Stop and return -1 if the length of s is less than the length of w.

nimi

Posted 2015-12-30T15:17:02.120

Reputation: 34 639

4

Python 2.7, 111 characters

Tries all starting positions (a) and checks of any of the letters match (using the list comprehension). It returns "None" (Python's "NULL") if nothing is found (the for loop end and nothing is returned, which defaults to "None".

def d(c,s):
 for a in range(len(c)):
  if a not in [((c+s)[a+i:]).index(l)+a for i,l in enumerate(s)]:
   return a

Testsuite:

cases = {
         ("BHGEFXWFTIUPITHHLPETTTCLOEWOELM","WETTERBERICHT"):13,
         ("ABCDEFGHIJKL","HELLO"):0,
         ("EEEEEEEEEEEE","HELLO"):-1,
         ("XEEFSLBSELDJMADNADKDPSSPRNEBWIENPF","DEUTSCHLAND"):11
        }

for idx,(code,string) in enumerate(cases):
    output=d(code,string)
    print "Case: {}: d({:<35},{:<16}) gives: {}. Correct answer is: {}.".format(idx+1,code,string,output,cases[(code,string)])

agtoever

Posted 2015-12-30T15:17:02.120

Reputation: 2 661

You actually have 114 bytes, not 111. Here is a 106-byte version: def d(c,s): for a in range(len(c)): if a not in[a+(c+s)[a+i:].index(l)for i,l in enumerate(s)]:return a – movatica – 2019-04-28T09:29:58.110

4

Brachylog, 48 bytes

[S:W]hlL,WlM,L-M=:0reI,'(0:MeJ+I=:SrmA,W:JmA),I.

This is a direct translation of my Prolog answer. The brachylog_main/2 generated predicate expects a list of two character codes strings with the coded string first as input, and returns the index as output, e.g. brachylog_main([`ABCDEFGHIJKL`,`HELLO`],R)..

Explanation

[S:W]                                            § Unify the input with the list [S,W]

     hlL,WlM,                                    § L and M are the length of S and W

             L-M=:0reI,                          § Enumerate integers between 0 and the 
                                                 § last possible index

                       '(                   ),I. § Unify the output with the current 
                                                 § enumerated integer if what's inside the 
                                                 § parenthesis cannot be proven to be true

                         0:MeJ                   § Enumerate integers between 0 and the
                                                 § length of the word desired

                              +I=:SrmA,W:JmA     § Check if both strings contain at matching
                                                 § indexes the same letter (unified with A)

Fatalize

Posted 2015-12-30T15:17:02.120

Reputation: 32 976

3

Japt, 12 bytes (non-competitive)

UàVr'."[^$&]

I'm gonna need some help with this one.

Mama Fun Roll

Posted 2015-12-30T15:17:02.120

Reputation: 7 234

Uhhh... Japt doesn't have .search? facepalm – ETHproductions – 2016-01-01T20:25:57.633

This can now be done with UàVr'."[^$&] for 12. – ETHproductions – 2016-01-12T04:06:54.147

Cool, we're winning now! – Mama Fun Roll – 2016-01-12T04:12:08.977

Since the latest revision of this answer uses functionality that postdates the question, I'm marking it as non-competitive. – Mego – 2016-01-12T04:55:16.093

Oh forgot about that :P Thanks! – Mama Fun Roll – 2016-01-12T05:00:59.103

2

Python 3, 79 bytes

lambda x,y:[sum(map(str.__eq__,x[i:],y))for i in range(len(x)-len(y))].index(0)

Try it online!

alexz02

Posted 2015-12-30T15:17:02.120

Reputation: 89

2

05AB1E, 14 bytes

ŒIgùDʒø€Ëà_}нk

Try it online or verify all test cases.

Explanation:

Π              # Get all substrings of the first (implicit) input
 Ig             # Get the length of the second input
   ù            # Only leave the substrings of that length
    D           # Duplicate the list of remaining substrings
     ʒ          # Filter the copy by:
      ø         #  Zip/transpose; swapping rows/columns the current substring with
                #  the second (implicit) input
       €Ë       #  Check for each if both characters are equal (1 if truthy; 0 if falsey)
         à      #  Get the maximum (basically equal to an `any` builtin)
          ≠     #  And invert the boolean (!= 1)
           }н   # After the filter: only leave the first substring
             k  # And get its index in the duplicated list (-1 if none are found)
                # (which is output implicitly as result)

Kevin Cruijssen

Posted 2015-12-30T15:17:02.120

Reputation: 67 575

2Dude, this was totally supposed to be @Emigna's answer ;). I wanted to come here and make a joke about him answering an adnan-question with almost-his-name in it. +1 (Noticed you answered 4 years after-the-fact after I posted this after-the-fact comment). – Magic Octopus Urn – 2019-04-29T21:31:30.240

@MagicOctopusUrn When I saw the challenge I thought the same thing, but @Emigna usually answers new answers and doesn't look that often at existing answers. So since this one didn't had any 05AB1E answers I figured I'd add one. You're indeed right that @Emigna would have been best suited to answer this challenge. ;p – Kevin Cruijssen – 2019-04-30T06:12:53.330

2

PHP – 155 bytes

<?php for($p=$argv[1],$q=$argv[2],$l=strlen($q),$i=0,$r=-1;$i<strlen($p)-$l;$i++)if(levenshtein($q,substr($p,$i,$l),2,1,2)==$l){$r=$i;break;}echo$r."\n";

Save as crack.php and run with the arguments in the command line. E.g.:

$ php crack.php BHGEFXWFTIUPITHHLPETTTCLOEWOELM WETTERBERICHT
13

user15259

Posted 2015-12-30T15:17:02.120

Reputation:

You can save 25 bytes and golf it down to 130 bytes: for($r=-1;$i<strlen($p=$argv[1])-$l=strlen($q=$argv[2]);$i++)if(levenshtein($q,substr($p,$i,$l),2,1,2)==$l&&$r=$i)break;echo"$r↵"; – insertusernamehere – 2015-12-30T19:03:41.543

@insertusernamehere - Wow, that's impressive! So much so that I wouldn't feel right using it! I thought I was being clever using levenshtein, but probably a straightforward iteration within an iteration could do it in fewer bytes. – None – 2016-01-01T20:30:02.997

2

TeaScript, 14 bytes 20

xc(yl#`[^${l}]

Similar to @aspillers clever JavaScript solution.

Non-competing because this uses features made after this contest.

Explanation

             // Implicit: x = 1st input, y = 2nd input
x            // First input
 c           // returns index of regex match
 yl#         // Loop through every char in `y`
    `[^${l}] // Replace template, ${l} because current char in `y`

Downgoat

Posted 2015-12-30T15:17:02.120

Reputation: 27 116

Does $& not work in place of ${l}? – ETHproductions – 2016-01-01T20:30:04.163

@ETHproductions not in this case because I'm using a loop rather than a replace – Downgoat – 2016-01-01T20:55:42.103

2

JavaScript, 129 121 118 119* 118 bytes

(w,t){for(j=0;(x=t.length)<(y=w.length);t=' '+t,j++){for(a=i=0;++i<y;)w[i]==t[i]?a=1:a;if(!a)break}return x==y?-1:j}

w is the coded message, t is the test string. This doesn't use regexes, but just compares letter by letter, shifting the test string (i.e. "WETTERBERICHT") by appending space before it. Easy and boring.


* test case with no match didn't work, now it does

nicael

Posted 2015-12-30T15:17:02.120

Reputation: 4 585

2

, 14 chars / 25 bytes

îĊⱮ(í,↪`⁅⦃$}]`

Try it here (Firefox only).

Kudos to @apsillers for the idea.

Explanation

               // implicit: î = input1, í = input2
îĊ             // search for first occurrence of:
  Ɱ(í,↪`⁅⦃$}]` // regex created by wrapping each word in [^ and ] (negation matches)

Mama Fun Roll

Posted 2015-12-30T15:17:02.120

Reputation: 7 234

Whoever downvoted this, is there a reason why? – Mama Fun Roll – 2015-12-31T18:32:43.163

2

Ruby, 43 36 bytes

edit: String interpolation inside string interpolation inside a regex, yikes.

The lazy approach: translates the word to a "negative" regex -- The =~ operator does the rest.

->m,w{m=~/#{"[^#{w.chars*'][^'}]"}/}

Test:

f=->m,w{m=~/#{"[^#{w.chars*'][^'}]"}/}

require "minitest/autorun"

describe :f do
  it "works for the given test cases" do
    assert_equal 13, f["BHGEFXWFTIUPITHHLPETTTCLOEWOELM", "WETTERBERICHT"]
    assert_equal 0, f["ABCDEFGHIJKL", "HELLO"]
    assert_equal nil, f["EEEEEEEEEEEE", "HELLO"]
    assert_equal 11, f["XEEFSLBSELDJMADNADKDPSSPRNEBWIENPF", "DEUTSCHLAND"]
    assert_equal nil, f["HKKH", "JJJJJ"]
  end
end

daniero

Posted 2015-12-30T15:17:02.120

Reputation: 17 193

1

Brachylog (v2), 16 bytes

bʰ↙.Pz₁≠ᵐzhc~hP∧

Try it online!

Brachylog is usually very good at failing when solving something is impossible.

This is not one of those times.

(takes input as a list [message, word]. The header prints it all very prettily but the output of the actual predicate is just a number if it succeeds)

                    The input
b                   with a number of letters removed from the beginning
 ʰ                  of its first element
  ↙.                where that number is the output
    P               is P
     z₁             which with its elements zipped, without cycling
       ≠ᵐ           contains no duplicate pairs
         z          and which zipped back
          h         has a first element
           c        which concatenated
            ~h      is the first element of
              P     P
               ∧    (which is not the output).

bʰ↙.Plᵐ≥₁∧Pz₁≠ᵐ∧ seems to work just as well for the same byte count.

Unrelated String

Posted 2015-12-30T15:17:02.120

Reputation: 5 300

1

Jolf, 14 bytes

Try it here!

 siρI".'[^$&]
_s            search
  i            input 1 for
    I          input 2
   ρ            replacing (2 byte rho character)
     ".'         all characters
        [^$&]    with that

Conor O'Brien

Posted 2015-12-30T15:17:02.120

Reputation: 36 228

1

Perl, 38 + 1 = 39 bytes

perl -E "$r=<>=~s!.![^$&]!gr;say@-if<>=~/$r/x" < input

where input looks like:

WETTERBERICHT
BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ

This is the same idea as the javascript one.

alexander-brett

Posted 2015-12-30T15:17:02.120

Reputation: 1 485

The 'x' is unnecessary – Zaid – 2016-01-02T08:37:17.330

1

Java, 136 Characters

Regex-based solution inspired by apsillers JavaScript version.

class L{public static void main(String[]a){a=a[0].split(a[1].replaceAll("(.)","[^$1]"));System.out.print(a.length>1?a[0].length():-1);}}

Minimal

Posted 2015-12-30T15:17:02.120

Reputation: 131

0

C++ (gcc), 160 153 150 bytes

#include<map>
int f(std::string c,std::string w){int i=-1,k,e=1;while(e&&w.size()+i++<c.size())for(e=k=0;k<w.size();)e+=c[i+k]==w[k++];return e?-1:i;}

Try it online!

movatica

Posted 2015-12-30T15:17:02.120

Reputation: 635

1

@ceilingcat: you can do 157 bytes

The code fails for two testcases though (as does my original one). I fixed it for a few extra bytes.

– movatica – 2019-04-29T21:02:27.060

1Plus, your initialization of k in the outer loop introduced another bug, where with each iteration, one less character was compared. – movatica – 2019-04-29T21:08:14.470

Turns out, it's even shorter without goto and without all the bugs... – movatica – 2019-04-29T21:30:06.253

0

Perl 5, 46 bytes

Uses @apsillers' regex idea.

$a=<>=~s/./[^$&]/gr;/$a/g;$_=(length$a)/-4+pos

Try it online!

Xcali

Posted 2015-12-30T15:17:02.120

Reputation: 7 671