Skip to main content
We’ve updated our Terms of Service. A new AI Addendum clarifies how Stack Overflow utilizes AI interactions.
Code Golf

Return to Answer

added 1438 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
fmain(c,n,c){forwhile(n=0;n-0xb33def<<7&~~(c=getchar());n=n<<5^putchar&n-0xb33def<<7)n=n<<5^putchar(c)/96*c);96*c;}

Try it online! Try it online!

How it works (WIP)

This is a full program. We define a function f for our purposes. To save bytes, it is declared with two argumentsargument that default to create a couple of local variables of type int. This is undefined behavior, but we will call the function as f(). gcc allows this; c andin practice, n will simply hold garbage values when f is called.

Whenbe initialized as f1 is calledwhen running the program without additional arguments, we enter a for loop. After initializing nc will hold the lower 32 bits of the pointer to0, we check if the argument vector

While the condition

n-0xb33def<<7&~~(c=getchar())&n-0xb33def<<7

holds. If it doesn't, we break out of the loop and end; if it does, wewe'll execute the afterthoughtwhile loop's body:

and start over.

To fully understand the condition, we must first examine the afterthoughtbody. For now, all we observe is that c=getchar() reads a single byte from STDIN (if possible) and stores it in the variable c.

Note that the lower 25 bits form the integer 0xb33def, which is the magic constant in the condition. While there is some overlap between the bits of two adjacent bytes, mapping bytes below 96 to 0 makes sure that there aren't any false positives.

The condition consists of two parts:

  • ~(getchar()) takes the bitwise NOT of the result of reading (or attempting to read) a byte from STDIN.

    If getchar succeeds, it will return the value of the read byte as an int. Since the input consists entirely of ASCII characters, the read byte can only have its lower 7 bits set, so the bitwise NOT will have its highest 25 bits set in this case.

    If getchar fails (no more input), it will return -1 and the bitwise NOT will be 0.

  • n-0xb33def<<7 subtracts the magic constant from before from n, then shifts the result 7 units to the left.

    If the last 5 read bytes were hello, the lowest 25 bits of n will be equal to 0xb33def and the subtraction will zero them out. Shifting the difference will yield 0 as the 7 highest bits will "fall off the left".

    On the other hand, if the last 5 read bytes were nothello, one of the lowest 25 bits of the difference will be set; after shifting, one of the highest 25 bits will be.

Finally, if getchar was successful and we didn't print hello yet, the bitwise AND, all of the highest 25 bits of the left operand and at least one of the highest 25 bits of the right one will be set. This way, & will yield a non-zero integer and the loop continues.

On the other hand, if the input is exhausted or we have printed hello already, one of the bitwise AND's operand will be zero, and so will the result. In this case, we break out of the loop and the program terminates.

f(c,n){for(n=0;n-0xb33def<<7&~(c=getchar());n=n<<5^putchar(c)/96*c);}

Try it online!

How it works (WIP)

We define a function f for our purposes. To save bytes, it is declared with two arguments to create a couple of local variables of type int, but we will call the function as f(). gcc allows this; c and n will simply hold garbage values when f is called.

When f is called, we enter a for loop. After initializing n to0, we check if the condition

n-0xb33def<<7&~(c=getchar())

holds. If it doesn't, we break out of the loop and end; if it does, we execute the afterthought

and start over.

To fully understand the condition, we must first examine the afterthought. For now, all we observe is that c=getchar() reads a single byte from STDIN (if possible) and stores it in the variable c.

Note that the lower 25 bits form the integer 0xb33def, which is the magic constant in the condition. While there is some overlap between the bits of two adjacent bytes, mapping bytes below 96 to 0 makes sure that there aren't any false positives.

main(n,c){while(~(c=getchar())&n-0xb33def<<7)n=n<<5^putchar(c)/96*c;}

Try it online!

How it works

This is a full program. We define a function f for our purposes. To save bytes, it is declared with two argument that default to int. This is undefined behavior, but in practice, n will be initialized as 1 when running the program without additional arguments, c will hold the lower 32 bits of the pointer to the argument vector

While the condition

~(c=getchar())&n-0xb33def<<7

holds, we'll execute the while loop's body:

To fully understand the condition, we must first examine the body. For now, all we observe is that c=getchar() reads a single byte from STDIN (if possible) and stores it in the variable c.

Note that the lower 25 bits form the integer 0xb33def, which is the magic constant in the condition. While there is some overlap between the bits of two adjacent bytes, mapping bytes below 96 to 0 makes sure that there aren't any false positives.

The condition consists of two parts:

  • ~(getchar()) takes the bitwise NOT of the result of reading (or attempting to read) a byte from STDIN.

    If getchar succeeds, it will return the value of the read byte as an int. Since the input consists entirely of ASCII characters, the read byte can only have its lower 7 bits set, so the bitwise NOT will have its highest 25 bits set in this case.

    If getchar fails (no more input), it will return -1 and the bitwise NOT will be 0.

  • n-0xb33def<<7 subtracts the magic constant from before from n, then shifts the result 7 units to the left.

    If the last 5 read bytes were hello, the lowest 25 bits of n will be equal to 0xb33def and the subtraction will zero them out. Shifting the difference will yield 0 as the 7 highest bits will "fall off the left".

    On the other hand, if the last 5 read bytes were nothello, one of the lowest 25 bits of the difference will be set; after shifting, one of the highest 25 bits will be.

Finally, if getchar was successful and we didn't print hello yet, the bitwise AND, all of the highest 25 bits of the left operand and at least one of the highest 25 bits of the right one will be set. This way, & will yield a non-zero integer and the loop continues.

On the other hand, if the input is exhausted or we have printed hello already, one of the bitwise AND's operand will be zero, and so will the result. In this case, we break out of the loop and the program terminates.

Spelling fixes
Source Link
Toby Speight
  • 7k
  • 1
  • 30
  • 43

n is updated by shifting it five bits to the left, then XORing the result with the result from the previous paragraph. Since an int is 32 bits wide (or so we assume in this answer), some of the shifted bits might "fall ofoff the left" (signed integer overflow is underfinedundefined behavior, but gcc behaves as the x64 instruction it generates here). Starting with an unknown value of n, after updating it for all characters of hello, we get the following result.

n is updated by shifting it five bits to the left, then XORing the result with the result from the previous paragraph. Since an int is 32 bits wide (or so we assume in this answer), some of the shifted bits might "fall of the left" (signed integer overflow is underfined behavior, but gcc behaves as the x64 instruction it generates here). Starting with an unknown value of n, after updating it for all characters of hello, we get the following result.

n is updated by shifting it five bits to the left, then XORing the result with the result from the previous paragraph. Since an int is 32 bits wide (or so we assume in this answer), some of the shifted bits might "fall off the left" (signed integer overflow is undefined behavior, but gcc behaves as the x64 instruction it generates here). Starting with an unknown value of n, after updating it for all characters of hello, we get the following result.

added 1216 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
char decimal binary (8 bits)
h 'h' 104 0 1 1 0 1 0 0 0
e 'e' 101 0 1 1 0 0 1 0 1
l 'l' 108 0 1 1 0 1 1 0 0
l 'l' 108 0 1 1 0 1 1 0 0
o 'o' 111 0 1 1 0 1 1 1 1

All of these fall in the range [96, 192), so c/96 will evaluate to 1 for each of these bytes, and to 0 for all remaining ASCII characters. This way, putchar(c)/96*c (putchar prints and returns its argument) will evaluate to c if c is `, a lowercase lettersletter, one of {|}~, or the DEL charactercharacter; for all other ASCII characters, butit will evaluate to 0.

n is updated by shifting it five bits to the left, then XORing the result with the result from the previous paragraph. Since an int is 32 bits wide (or so we assume in this answer), some of the shifted bits might "fall of the left" (signed integer overflow is underfined behavior, but gcc behaves as the x64 instruction it generates here). Starting with an unknown value of n, after updating it for all other ASCII characters of hello, we get the following result.

 n ?????????????????????????|???????
'h' | 01101000
'e' | 01100101
'l' | 01101100
'l' | 01101100
'o' | 01101111
-----------------------------+--------------------------------
 <------ discarded ------>|???????0101100110011110111101111

Note that the lower 25 bits form the integer 0xb33def, which is the magic constant in the condition. While there is some overlap between the bits of two adjacent bytes, mapping bytes below 96 to 0 makes sure that there aren't any false positives.

char decimal binary (8 bits)
h  104 0 1 1 0 1 0 0 0
e  101 0 1 1 0 0 1 0 1
l  108 0 1 1 0 1 1 0 0
l  108 0 1 1 0 1 1 0 0
o  111 0 1 1 0 1 1 1 1

All of these fall in the range [96, 192), so c/96 will evaluate to 1 for each of these bytes, and to 0 for all remaining ASCII characters. This way, putchar(c)/96*c (putchar prints and returns its argument) will evaluate to c if c is `, a lowercase letters, one of {|}~, or the DEL character, but to 0 for all other ASCII characters.

char decimal binary (8 bits)
'h' 104 0 1 1 0 1 0 0 0
'e' 101 0 1 1 0 0 1 0 1
'l' 108 0 1 1 0 1 1 0 0
'l' 108 0 1 1 0 1 1 0 0
'o' 111 0 1 1 0 1 1 1 1

All of these fall in the range [96, 192), so c/96 will evaluate to 1 for each of these bytes, and to 0 for all remaining ASCII characters. This way, putchar(c)/96*c (putchar prints and returns its argument) will evaluate to c if c is `, a lowercase letter, one of {|}~, or the DEL character; for all other ASCII characters, it will evaluate to 0.

n is updated by shifting it five bits to the left, then XORing the result with the result from the previous paragraph. Since an int is 32 bits wide (or so we assume in this answer), some of the shifted bits might "fall of the left" (signed integer overflow is underfined behavior, but gcc behaves as the x64 instruction it generates here). Starting with an unknown value of n, after updating it for all characters of hello, we get the following result.

 n ?????????????????????????|???????
'h' | 01101000
'e' | 01100101
'l' | 01101100
'l' | 01101100
'o' | 01101111
-----------------------------+--------------------------------
 <------ discarded ------>|???????0101100110011110111101111

Note that the lower 25 bits form the integer 0xb33def, which is the magic constant in the condition. While there is some overlap between the bits of two adjacent bytes, mapping bytes below 96 to 0 makes sure that there aren't any false positives.

added 1509 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading
added 8 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading
added 9 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading
added 6 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading
added 7 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading
added 8 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading
Rollback to Revision 3
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading
added 9 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading
added 3 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading
added 7 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading
deleted 3 characters in body
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading
Source Link
Dennis
  • 211.7k
  • 41
  • 380
  • 830
Loading

AltStyle によって変換されたページ (->オリジナル) /