What is this code doing. Check two strings for anagrams

Viewed 111

This code checks if two strings for an anagram. Can you please explain how it works what is it even doing.

#include <stdio.h>

int t[256],i;
int main(int c)
{
    for(;c+3;)
        (i=getchar())>10?t[i]+=c:(c-=2);

    for(i=257;--i&&!t[i-1];);
    puts(i?"false":"true");    
}

Here's what I've understood while poking at the source code: Its maintaining an array t[], and storing values at index = character's ascii value. The value stored is 1 for the first string's characters and -1 for the second string's characters. If a character is in both the strings, the value stored in it is zero. 1 + (-1). The first for loop is the input.

can you explain what this loop is checking, and how does it set up the value of variable i : for(i=257;--i&&!t[i-1];);

Code from: https://developerinsider.co/find-anagram-string-programming-puzzles/

2 Answers

Just for fun, let's break it down:

int t[256],i;     // Relying on the fact that global vars are initialized

int main(int c)   // Not a legal signature for main
{
    for(;c+3;)    // What is c's initial value? Assuming it is 1
        (i=getchar())>10?t[i]+=c:(c-=2);  // Read a char from stdin
                                          // If it is not a newline add c (1 or -1) to t[i]
                                          // - that is: increment or decrement letter count
                                          // If it is the 1st newline, c = c - 2 = -1;
                                          // So for the first word, increment letter count
                                          // For 2nd word, decrement letter count
                                          // When a 2nd newline is found c = c - 2 = -3
                                          // This ends the loop since -3 + 3 = 0

    for(i=257;--i&&!t[i-1];);             // Starting at the end of the array, check
                                          // each char code. They should all be 0
                                          // if not, it wasn't an anagram
    puts(i?"false":"true");               // If i did not reach 0 in previous loop,
                                          // not an anagram
}

I need a drink now.

Code golfing in a nutshell

Do you golf ? No, I mean this kind of golf

#include <stdio.h> // for getchar lib, not even mandatory to compile...

int t[256],i; // t is where you store the user input
int main(int c) // reusing the register of argc, equal to 1 // NB: if using any argument your program will fail but ok.
{
    for(;c+3;) // it loops until c reach -3, currently at 1 
        (i=getchar())>10?t[i]+=c:(c-=2); 

// i=getchar() // get user input
// (i=getchar())>10? // if user input > 10 means as long as the user 
// does not press enter, as '\n' is equal to 10.
// t[i]+=c:(c-=2); // if user input is valid (>10) then the array t at index of your character will either be incremented (if first input) 
// or decremented (if second input, as the first '\n' will decrement t[i] since c == -1) as c will be respectively equal to +1 and -1.
// then it will exit the loop on the second input (c = -3)

    for(i=257;--i&&!t[i-1];); 
// start from the end, i is predecrement and we access index i-1 to automatically 
// exit the loop when i reach 1, no need to check with --i>=0 (--i    >=0    is 3 chars instead of
// 2 char for t[i    -1    ]). If t[i-1] is equal 0 it means that the // character was 
// effectively cancelled out by the second string so t[i-1] == 0 
// and !t[i-1] are equivalent
    puts(i?"false":"true");  
// at the end --i will decrement i from 1 to 0 and exit without 
// reaching !t[0-1], if i is not 0 then it means the break occured 
// before going through all the characters.   
}

NB: Of course do not ever create program like this if it is not for golfing purpose.

Related