Verify every letter is unique.

Microsoft Windows xp professional w/serv...
December 19, 2009 at 01:00:58
Specs: Windows XP
Deleted my question for now. The setup may be different than I thought.
Sky

--- Setup confirmed. Please see next post. ---


See More: Verify every letter is unique.

Report •


#1
December 19, 2009 at 01:30:06
Setup is confirmed so reposting my question.

What's the easiest way to verify every letter is unique?

I have variables as follows:
R1=E, R2=F, R3=G, R4=H, R5=I, R6=
B1=J, B2=K, B3=L, B4=M, B5=N, B6=

The number of variables can vary from 1 to 10.
The letters can be anything between D to Z.
The last variable is always blank and acts as a terminator only.

For example I could have:
R1=M, R2=N, R3=
B1=R, B2=S, B3=T, B4=

or I could have:
R1=
B1=E, B2=F, B3=G, B4=

I want to verify that every letter is unique and there are no duplicated letters. Aside from the brute force method of many IF compare statements like

if "%B1%"=="%B2%" goto :Error
if "%B1%"=="%B3%" goto :Error
etc.

is there an easier way?

In case anyone needs the variables, here they are to save you some typing:

:: These variables would be set up by the user so duplicate letters are possible.
set R1=E
set R2=F
set R3=G
set R4=H
set R5=I
set R6=
set B1=J
set B2=K
set B3=L
set B4=M
set B5=N
set B6=

Thanks,
Sky


Report •

#2
December 19, 2009 at 01:50:15
do you definitely have to do this in batch? there are other tools that does this better and easier.

GNU win32 packages | Gawk


Report •

#3
December 19, 2009 at 02:19:34
Do you want to check for dups in var NAMES or var VALUES?

Case sensitive?


=====================================
Helping others achieve escape felicity

M2


Report •

Related Solutions

#4
December 19, 2009 at 02:49:39
-------------------------
ghostdog said:
do you definitely have to do this in batch? there are other tools that does this better and easier.
-------------------------

Yes, definitely in batch as I don't want to force the user to load any other program.

Thanks,
Sky


Report •

#5
December 19, 2009 at 03:09:56
-------------------------
Mechanix2Go said:
Do you want to check for dups in var NAMES or var VALUES?
Case sensitive?
-------------------------

Check for dups in values. For example, variable R1 contains the letter E. I want to insure that the letter E is not in any other variable, R2-R5 and also not in variables B1-B5.

Not case sensitive as I convert all user input to uppercase.

If it helps to understand what I need to do, here's some code that I'm testing (thanks to tvc in another thread):

:: This code is incomplete. It only compares up to R4. It needs to
:: compare all the way up to - if "%B4%" NEQ "%B5%"

if "%R1%" NEQ "%R2%" if "%R1%" NEQ "%R3%" if "%R1%" NEQ "%R4%" if "%R1%" NEQ "%R5%" if "%R1%" NEQ "%B1%" if "%R1%" NEQ "%B2%" if "%R1%" NEQ "%B3%" if "%R1%" NEQ "%B4%" if "%R1%" NEQ "%B5%" if "%R2%" NEQ "%R3%" if "%R2%" NEQ "%R4%" if "%R2%" NEQ "%R5%" if "%R2%" NEQ "%B1%" if "%R2%" NEQ "%B2%" if "%R2%" NEQ "%B3%" if "%R2%" NEQ "%B4%" if "%R2%" NEQ "%B5%" if "%R3%" NEQ "%R4%" if "%R3%" NEQ "%R5%" if "%R4%" NEQ "%R5%" goto :CONTINUE
echo.
echo --- DUPLICATE DRIVE LETTERS ---
goto :ERROR

:CONTINUE

Thanks,
Sky


Report •

#6
December 19, 2009 at 03:59:57
"Yes, definitely in batch as I don't want to force the user to load any other program."

LOL vbs is supported by default in windows.


=====================================
Helping others achieve escape felicity

M2


Report •

#7
December 19, 2009 at 10:43:09
-------------------------
Skyhawk said:
"Yes, definitely in batch as I don't want to force the user to load any other program."

Mechanix2Go said:
LOL vbs is supported by default in windows.
-------------------------

That would be the interpter, not the program that does the actual work which the user would still have to load.

Legally, if I tried to sell my program (not just this one but any one), wouldn't I have to get permission to include programs that other people wrote even if the program is free? (I think they're usually free for personal use only.)

EDIT: Just dawned on me. Did you mean I can call a function in VBS that can do what I need?

Sky


Report •

#8
December 19, 2009 at 11:15:47
Here's another take on my question. All of the letters are assembled as a string. The problem then would be to confirm that every letter in the string is unique.

set string=%R1%%R2%%R3%%R4%%R5%%B1%%B2%%B3%%B4%%B5%
echo string is %string%

Echo displays "string is EFGHIJKLMN"


Report •

#9
December 19, 2009 at 14:19:47
Got a working version that verifies every letter is unique. It assembles the values in a string and then does compares on the characters in the string.

I had to change my user input philosophy. When the user finishes entering the Rn values, the last value will be blank (zero lenth string). When the user finishes entering the Bn values, the last value will be a # character.

This works well since the blank Rn value is not assembled in the string while the # Bn value is assembled as the last character in the string. So the string ends up looking like:

EFGHIJKLMN#

with no space between the I and J characters. But even if there was a space, it wouldn't have affected the results I don't think.

Here's my working program in case it helps someone else. Or maybe someone can come up with a simpler version. The meat of the program is from :LOOP1 to :ERROR".

-------------------------
@echo off
setLocal EnableDelayedExpansion

:: These variables would be set up by the user
set R1=E
set R2=F
set R3=G
set R4=H
set R5=I
set R6=
set B1=J
set B2=K
set B3=L
set B4=M
set B5=M
set B6=#

:BEGIN
cls
echo.
set S=%R1%%R2%%R3%%R4%%R5%%R6%%B1%%B2%%B3%%B4%%B5%%B6%
echo string is %S%
pause
:: echo displays "string is EFGHIJKLMN#"

:: Set initial counts
set P1=0
set P2base=1
set P2=%P2base%

:LOOP1
:: Compare letters. Check for end of string # to end passes.
:: Check for end of string # to exit when no dups found.
if "!S:~%P1%,1!"=="!S:~%P2%,1!" goto :ERROR
if "!S:~%P2%,1!"=="#" goto :PASS_BUMP
if "!S:~%P1%,1!"=="#" goto :CONTINUE
set /a P2+=1
goto :LOOP1
:PASS_BUMP
set /a P1+=1
set /a P2base+=1
set P2=%P2base%
goto :LOOP1

:ERROR
echo.
echo --- Duplicate letter found = !S:~%P1%,1! ---
pause
goto :ENTER_AGAIN

:ENTER_AGAIN
echo.
echo Do user input again
pause
goto :BEGIN

:CONTINUE
echo.
echo --- No duplicates found ---
pause
:: Continue with program
goto :END

:END
-------------------------

--- IGNORE THIS PARAGRAPH. See EDIT below. ---
One thing I need help on. When I tried to do the echo command in the :ERROR routine as:
echo Dup letter is !S:~%P1%,1!
It wouldn't work. So I had to set that value in the variable named "var" first and then do the echo. Any suggestions on how to do it in the echo command without having to set it in a variable first?

EDIT: nbrane let me know that the echo command should have worked. He/she is correct and I must have had a typo in my batch code while testing. I corrected the echo code above and eliminated the unnecessary set var statement.

Sky


Report •

#10
December 19, 2009 at 15:33:47
I'm not sure about #, but this should test to see if each
variable contains a unique letter(sort of)....

set letters=abcdefghijklmnopqrstuvwxyz
for %%a in (b r) do (
    for /l %%b in (1 1 6) do (
        if defined %%a%%b (
            for /f %%c in ("!%%a%%b!") do (
                if "!letters!"=="!letters:%%c=!" (
                    echo A duplicate letter exists^(!%%a%%b!^)^^!
                    goto error
                ) else (
                    set letters=!letters:%%c=!
                )
            )
        )
    )
)


Batch Variable how to


Report •

#11
December 19, 2009 at 16:58:12
Hi Judago,

Looks interesting. Gotta go to a party now so will check it out tomorrow. BTW, I think it was you who wrote the write-up about how to use multiple % in different levels. Thanks for that.

Thanks,
Sky


Report •

#12
December 19, 2009 at 19:20:09
this can be easily done using dictionary storage. eg in vbscript

Set dict = CreateObject("Scripting.Dictionary")	
strUserInput = WScript.Arguments.Item(0)
For i=1 To Len(strUserInput)
	ch = Mid(strUserInput,i,1)
	If Not dict.Exists(ch) Then
		dict.Add ch,"1"
	Else
		WScript.Echo "duplicate: "& ch
	End If 
Next

save as testdups.vbs and pass the string you want to check on the command line

C:\test>cscript //nologo testdups.vbs "abcdefaghib"
duplicate: a
duplicate: b

C:\test>

GNU win32 packages | Gawk


Report •

#13
December 19, 2009 at 21:52:43
Hi ghostdog,

Thre was not a doubt in my military mind that vbs was the way to go. Nor that you would show us how.

Thanks


=====================================
Helping others achieve escape felicity

M2


Report •

#14
December 20, 2009 at 11:21:28
Judago,

I tried to run your code as follows: (d is duplicated)

@echo off
setLocal EnableDelayedExpansion
set letters=abcdefghijkldnopqrstuvwxyz
for %%a in (b r) do (
    for /l %%b in (1 1 6) do (
        if defined %%a%%b (
            for /f %%c in ("!%%a%%b!") do (
                if "!letters!"=="!letters:%%c=!" (
                    echo A duplicate letter exists^(!%%a%%b!^)^^!
                    goto error
                ) else (
                    set letters=!letters:%%c=!
                )
            )
        )
    )
)
echo Finished test
pause

Nothing displays except "Finished test".
Am I using your code incorrectly?

Sky


Report •

#15
December 20, 2009 at 11:41:31
Ghostdog,

I tried running your VBS method by inserting the call in my test program as follows: (I named your VBS code as "Finddups.vbs".)

@echo off
setLocal EnableDelayedExpansion

:: These variables would be set up by the user
set R1=E
set R2=F
set R3=G
set R4=H
set R5=I
set B1=J
set B2=K
set B3=L
set B4=M
set B5=N

:BEGIN
cls
echo.

:: Assemble string from user variables
set S=%R1%%R2%%R3%%R4%%R5%%R6%%B1%%B2%%B3%%B4%%B5%%B6%
echo string is %S%
pause
:: echo displays "string is EFGHIJKLMN"

call Finddups.vbs %S%

echo.
pause
:END

I don't get any result displayed whether there is, or is not a duplicate letter in the string. Am I calling your VBS code correctly?

The other thing is that it is rather slow. It takes 3.06 seconds (using stopwatch) for the last pause to show. My batch file method is almost instantaneous (too fast to click stopwatch)

Thanks,
Sky


Report •

#16
December 20, 2009 at 15:38:51
why do you use call?? use cscript to execute the vbs script,
like what i posted.......

GNU win32 packages | Gawk


Report •

#17
December 20, 2009 at 15:41:01
why do you use call?? use cscript to execute the vbs script,
like what i posted.......if you want to display your own custom
messages, change the vbs to reflect that. my script is not a
"do it all for you" script and you should read the
documentation, do research on vbs etc etc in order to do
EXACTLY what you want.

GNU win32 packages | Gawk


Report •

#18
December 20, 2009 at 16:03:19
-------------------------
ghostdog said:
why do you use call?? use cscript to execute the vbs script,
like what i posted.......if you want to display your own custom
messages, change the vbs to reflect that.
-------------------------

If you looked at the subcategory for my post, it says "Batch"! My queston was how to find duplicate letters in BATCH code.

-------------------------
ghostdog said:
my script is not a "do it all for you" script and you should read the documentation, do research on vbs etc etc in order to do
EXACTLY what you want.
-------------------------

So why the sarcastic comments? I never asked for VBS code and maybe you should read the subcategory before responding if you're going to get sarcastic because of responses to your post.

I thought you were offering a way to call your VBS code from my batch program to help me out. I see now that I was wrong.

Mind boggling how a question asked in good faith can turn ugly.
Sky


Report •

#19
December 20, 2009 at 16:20:10
do you really know the meaning of batch?? a batch file a
series of commands put together to do work. you can put
ping, findstr and any other executable commands in a text
file and call it a batch. Including executing the vbs engine
cscript/wscript. they are all exe files.
I had already shown you how to call the vbs using cscript on
the command line. all you need to do is put that command
into your batch file, but you did it with a call instead. not my
fault if you are not following instructions.

GNU win32 packages | Gawk


Report •

#20
December 20, 2009 at 18:18:12
is there a reason that you suspend validation of duplicate user-input until after all inputs? if not, it seems like it would be much easier to validate at the time of input. this code will attempt to pull double-duty of ignoring case on input and checking if input data is already in the que (a=A and if a or A
already entered, tell the user to try another letter):

@echo off && setlocal enabledelayedexpansion
:: primary user-interface
:one
set xx=
set /p xx=letter:
set test=!xx!
:: sequence ended by null entry
if "!test!" equ "" goto :ex
if defined !test! echo drive letter already accounted for...
:: since var. names are not case sensitive, this works for both a and A
:: i know this looks stupid, but it seems to work: var xx receives it's own
:: name (f/e: xx is A, var A is assigned value "A"
set !xx!=!xx!
::debugging dialog...
echo xx is [!xx!]
echo !xx! is [!xx!]
goto :one
:ex

why wait till user has entered wrong data and make him enter every value over again? better to validate asap and let him correct a single mistake... but you might have good reasons.


Report •

#21
December 20, 2009 at 18:45:03
-------------------------
nbrane said:
is there a reason that you suspend validation of duplicate user-input until after all inputs? if not, it seems like it would be much easier to validate at the time of input. this code will attempt to pull double-duty of ignoring case on input and checking if input data is already in the que (a=A and if a or A
already entered, tell the user to try another letter): .....snip.....
-------------------------

nbrane,

Your method is awesome!

I only suspended testing for duplicates because it seemed easier to do it that way. Also, usage is for optical drive letters and most users probably would have 2 or 3 drives max so it wouldn't require a lot of re-entry. But your method of catching errors during input is much, much better.

I'm going to adapt your method for my program.

Thanks a lot!
Sky


Report •

#22
December 20, 2009 at 20:32:40
I have no doubt that the vbs is probably better...

As for:

Nothing displays except "Finished test".
Am I using your code incorrectly?

You didn't have a label named error after the script(I forgot to include it) so it won't break the loop....


Batch Variable how to


Report •

#23
December 20, 2009 at 21:32:34
-------------------------
Judago said:
You didn't have a label named error after the script(I forgot to include it) so it won't break the loop....
-------------------------

Thanks for your response. Didn't do more testing since I'm working on using nbrane's realtime duplicate letter checking method.

Sky


Report •

#24
December 21, 2009 at 02:56:27
This is getting a bit long in the tooth. But before we close it out, CALL is used in a batch to CALL another batch.

In NT it can also call a sub, but that's another story.

As for interpreted vs compiled, if it ain't compiled, it's interpreted. True for BAT BAS VBS...

As to what's "legal", this is not the lawyers-in-love forum.


=====================================
Helping others achieve escape felicity

M2


Report •


Ask Question