mIRC Home    About    Download    Register    News    Help

Topic Options
#93183 - 07/08/04 07:33 PM random
xhine Offline
Ameglian cow

Registered: 15/07/04
Posts: 21
is there a way to check if a randomly ordered word equals the original?

example:
rmci

and it will play around with it and see if it can find mirc(the actual word will be given, just need it to return true or false if it == the word)

Top
#93184 - 07/08/04 07:50 PM Re: random
Smay Offline
Pikka bird

Registered: 07/08/04
Posts: 16
Loc: Illinois
I'm assuming this means that you know what the original word was, otherwise you obviously couldn't compare.. there are 2 ways to do it that i can think of, one being much better than the other of course smile

The first, and best way to do it, is to iterate through each character in the known word and try to find a match in the known word. Build a string as you match, and make sure there are no letters left, and each letter is only used once. Now of course that description makes no sense, so an example, using what you provided.
Known word - mirc
Random word - rmci
Match String - empty

So we start with the first character of the known word, 'm'. Search through the random word until you find an 'm', which in this case will be the 2nd character.
Add this character to a new variable, and remove it from the random word. So now you've got:
Known Word - mirc
Random Word - rci
Match String - m

Now move to the 2nd character, 'i'. Search through the random word until you find an 'i', repeat above.
Known Word - mirc
Random Word - rc
Match String - mi

etc..

You'll end up with a few cases to check for to see if you've found a match:
1. There's a letter in the known word that isn't in the random word --> return false
2. You've iterated through the entire known word, and the random word still has character in it --> return false
3. The match string == known word, and random word = $null --> return true.

If you want I'll code it up, but it's a better learning experience if you do it yourself smile
_________________________
Smay!

Top
#93185 - 07/08/04 08:07 PM Re: random
xhine Offline
Ameglian cow

Registered: 15/07/04
Posts: 21
well, i tried something like this
Code:
 
randomGen {
  set %theMatch 
  var %word = $1
  var %random = $2
  var %i = 1
  while (%i < $calc($len(%word) + 1)) {
    var %x = 1
    while (%x < $calc($len(%random) + 1)) {
      if ($left(%word,%i) isin %random) {
        set %theMatch %thematch $+ $left(%word,%x)
      }
      inc %x
    }
    inc %i
  }
  echo -a %theMatch
}
 

:P
didnt work all that good..


edit: oh my bad, i see what my rpoblem is :tongue:
how do i split up the letters one by one?


Edited by xhine (07/08/04 08:12 PM)

Top
#93186 - 07/08/04 08:20 PM Re: random
Coolkill Offline
Hoopy frood

Registered: 09/12/02
Posts: 788
Loc: Wales, United Kingdom.
Use $mid([color:red]string, n, 1) [/color]

Where, 'n' is the Nth character, and '1' is the number of characters you wish to return (1).

For example;

$mid(abc123,1,1) - returns 'a'
$mid(abc123,2,1) - returns 'b'
$mid(abc123,3,1) - returns 'c'
$mid(abc123,4,1) - returns '1'
$mid(abc123,5,1) - returns '2'
$mid(abc123,6,1) - returns '3'

EDIT: To save you some time...

alias stmatch {
if (!$2) { return ERR }
elseif ($len($1) != $len($2)) { return $false }
else {
var %i = $len($1)
while (%i) {
if ($mid($1,%i,1) !isin $2) { return $false }
dec %i
}
return $true
}
}


Syntax: //echo -> $stmatch(irmc,mirc)

Eamonn.

Top
#93187 - 07/08/04 08:28 PM Re: random
Smay Offline
Pikka bird

Registered: 07/08/04
Posts: 16
Loc: Illinois
You don't really need the inner while loop in your code, because it is going to execute an un-necessary number of times.
You really only need to check to make sure the current character in %word exists in %random (use $pos or $count). Then if it does, use $pos to find the character and remove it from %random (using a combination of $left and $right).

The reason your code wasn't working was because the statement:
if ($left(%word,%i) isin %random)
Is comparing %word in increasing sizes to %random.
If %word = mirc, %random = rmci
The first iteration of the while loop, it'll work fine --> if (m isin rmci)
The 2nd iteration of the while loop is where it breaks --> if (mi isin rmci)
As you can see, it'll fail because you're trying to compare 2 characters instead of 1. You need to only compare 1 character at a time.

I've modified your code a little, and below it I'm putting explanations of what I did.
Code:
alias randomGen {
    set %theMatch
    var %word = $1
    var %random = $2
    var %i = 1
    while (%i <= $len(%word)) {    
        var %char $mid(%word,$eval(%i), 1)
        if (%char isin %random) {
            set %theMatch %thematch $+ $mid(%word,$eval(%i), 1)
        }
        inc %i
    }
    echo -a %theMatch
}

1. while (%i <= $len(%word))
I changed the while loop to use <= instead of <, and eliminated the $calc you had there.

2. var %char $mid(%word,$eval(%i), 1)
$mid(%word,$eval(%i), 1) will take 1 characater from %word, starting at position %i. It will save this char in %char

3. if (%char isin %random)
If the character is in %random, this will succeed.

4. set %theMatch %thematch $+ %char
Adds the character to %theMatch

Now, the things I left out.. You need to remove the character from %random, or else you'll get false matches. for example, if %word = radar, and %random = ard, the code above will still say you have a match because technically %random has all of the characters that %word has. Also, after the while loop you'll want to make sure that %random is empty if you care about an exact match.
_________________________
Smay!

Top
#93188 - 07/08/04 09:58 PM Re: random
Kelder Offline
Hoopy frood

Registered: 12/04/03
Posts: 701
Loc: Leuven, Belgium
* Kelder tried to resist using regex and failed miserably frown :tongue:

alias check {
if ($len($1) != $len($2)) return $false
var %t = $2, %i = $v1
while (%i) {
if (!$regsub(%t,/\Q $+ $mid($1,%i,1) $+ \E/[color:red]i
,,%t)) return $false
dec %i
}
if (%t == $null) return $true
else return $false
}[/color]

usage: echo -s $check(word,rodw)
If the i is present it's case insensitive, if you keep it out it's case sensitive.
Also make sure the code is really on different lines and not one long line (forum pasting bug)

(Thanks to Online for the tips smile )


Edited by Kelder (07/08/04 10:24 PM)

Top
#93189 - 08/08/04 02:46 PM Re: random
FiberOPtics Offline
Hoopy frood

Registered: 05/02/04
Posts: 2019
Loc: Leuven, Belgium
Hi,

5. PCRE does support the \Q...\E escape for quoting sub-
strings. Characters in between are treated as literals.

Nice, didn't know that.

Greets
_________________________
Gone.

Top
#93190 - 08/08/04 04:34 PM Re: random
Online Offline
Hoopy frood

Registered: 09/12/02
Posts: 1922
Like many other exciting techniques, this one was also introduced by qwerty wink

See the search page for a couple of examples.

Top
#93191 - 08/08/04 06:12 PM Re: random
FiberOPtics Offline
Hoopy frood

Registered: 05/02/04
Posts: 2019
Loc: Leuven, Belgium
Thanks.

In September, I'll finally have some free time to improve my regex skills, and get to know those nifty things smile

Greets
_________________________
Gone.

Top
#93192 - 08/08/04 06:25 PM Re: random
Online Offline
Hoopy frood

Registered: 09/12/02
Posts: 1922
By the way, here's a different approach. It's limited to ~200 characters.

alias equals {
  • ; Usage: $equals(word, dowr)
    ;
    ; use $lower($1) and $lower($$2) for case-insensitiveness.
    bset -t &a 1 $1
    bset -t &b 1 $$2
    if $sorttok($bvar(&a,1-),32) != $sorttok($bvar(&b,1-),32) {
    return 0
    }
    return 1
}

Top