2

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/

Neon
  • 41
  • 5
  • 7
    Looking at this gives me a headache. Find a new tutorial. – 001 Mar 06 '21 at 01:47
  • 1
    Well it's a mess, but what if you *decode* it a bit, `for (i = 257; --i != 0 && t[i-1] == 0;) ;`. `;` in the end is a null statement and performs no operations. – alex01011 Mar 06 '21 at 02:03

2 Answers2

3

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.

001
  • 13,291
  • 5
  • 35
  • 66
1

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.

Antonin GAVREL
  • 9,682
  • 8
  • 54
  • 81
  • 1
    Hey man, Very detailed explanation. Thanks. Maybe you can edit and add this: C treats 0 as false, any other number is True. This is the reason the second loop exits when i = 1. --i makes it 0(which is false). Can you explain Why c takes the value of 1? and What is argc? (do you mean argument c? or something else) – Neon Mar 10 '21 at 20:58
  • 1
    You're welcome! c takes the value of 1 because c (in reality argc) is equal to the number of argument of your program, including your program name, so if you launch ./a.out or whatever names you compiled your program with -o, argc = 1. https://www.gnu.org/software/libc/manual/html_node/Program-Arguments.html – Antonin GAVREL Mar 10 '21 at 21:07