Remove duplicate elements of string1 from string2 in Tcl - scripting

I want to remove duplicate elements of string1 from string 2 and then output new string. My code works only if duplicate elements are in sequential order.
I want to work it any order of elements. Please advise.
Current Code:
set str1 "a 1 b 2 c 3 X Y Z"
set str2 "a 1 b 2 c 3 P Q R"
set results {}
set results [lmap a_elem $str1 b_elem $str2 {
if {$a_elem != $b_elem} {string cat $b_elem} else continue
}]
puts $results
Output of the following code :
P Q R
However, if
set str1 "a 1 b 2 c 3 X Y Z"
set str2 "P a 2 1 R c Q 3 b"
then Output will be : P a 2 1 R c Q 3 b
Basically same as str2 without the duplicate elimnation.

If you want to output those elements of the list in str2 that are nowhere in str1, you should first build a dictionary of the elements of str1 so that you can use efficient lookup (dicts are internally hash tables). You are strongly recommended to use a procedure for this as it makes the implementation rather more efficient.
proc removeItems {str1 str2} {
foreach item $str1 {
dict set items $item ""; # Value unimportant
}
lmap item $str2 {
if {[dict exists $items $item]} continue
string cat $item
}
}
puts [removeItems "a 1 b 2 c 3 X Y Z" "P a 2 1 R c Q 3 b"]
# P R Q
The code naturally assumes that the order of str2 is important.

If performance is not important, you can use the more straight forward:
set results [lmap elem $str2 {
if {$elem ni $str1} {string cat $elem} else continue
}]

Related

F# Clearly defined mutable variable errors it is not a mutable variable

I have several mutable variables in my code. All of them works except one!
Variable d gets several errors like
learn.fsx(33,25): error FS0027: This value is not mutable. Consider using the mutable keyword, e.g. 'let mutable d = expression'
The problem is that when you look in my code then the variable has clearly been defined as a mutable variable.
I think it is a necessity since the only thing I can think of should cause the problem is that it is something after the variable definition that makes it immutable again.
let seq = [2;2;3;3;5;6]
let exp = [[];[]]
let mutable points = 0
let mutable e = 1
let mutable state = ""
let mutable d = 1
let rec guess (x:int) =
match points with
|100 -> "learned"
|_ -> match seq.[x] with
|d -> match (exp.[((List.length exp)-2)]) with
|[] -> if state = "right" then
exp.[((List.length exp)-1)]#[d]
else
state <- "right"
exp#[[d]]
points <- points + 1
if d = 6 then
d <- 1
else
d <- d + 1
if x = 5 then
(guess 0)
else
(guess (x+1))
|_ -> if state = "right" then
exp.[((List.length exp)-1)]#[d]
else
state <- "right"
exp#[[d]]
if (List.length exp.[((List.length exp)-2)]) >= 2 then
d <- (exp.[((List.length exp)-2)]).[e]
else
if d = 6 then
d <- 1
else
d <- d + 1
e <- e + 1
if x = 5 then
(guess 0)
else
(guess (x+1))
|_ -> points <- points - 1
e <- 1
state <- "wrong"
if d = 6 then
d <- 1
else
d <- d + 1
if x = 5 then
(guess 0)
else
(guess (x+1))
Using d in the match causes that version of d to be used instead of the d defined as a mutable value.
Change the name of the value to something else of use 1 directly.
for example: | d -> match (exp.[((List.length exp)-2)]) can become | 1 -> match (exp.[((List.length exp)-2)])

Given value p, return last element of sequence < p - Fortran

I have a sequence of numbers as follows:
1 , 1, 5, 13, 41, 121, 365, ....
The first two values are:
N(1) = 1 and N(2) = 1
As from 3rd value, N(i) = 2*N(i-1) + 3*N(i-2)
The issue I am facing with is: If I give an argument of p, it should return me the last values of the sequence < p (Using fortran77).
For instance, if p = 90, it should return the value 41.
a = 1
b = 1
while b < p:
c = 2 * b + 3 * a
a = b
b = c
return a
The Fortran equivalent is:
function fct(p) result(a)
integer, intent(in) :: p
integer :: a, b, c
a = 1
b = 1
do while (b < p)
c = 2 * b + 3 * a
a = b
b = c
enddo
end function
program test
integer :: fct
external fct
print *,fct(90)
end program
Assuming you already have the sequence in a variable lst, and p set,
max(filter(lambda x:x<=p, lst))
def get_last_element(p):
n1 = 1
n2 = 1
while True:
if n2 > p:
return n1
n1, n2 = n2, 2*n2 + 3 * n1
print(get_last_element(90))
I wrote a piece of code in Fortran 2003. I defined a type which has memory for two last parts of the sequence.The procedure is a recursive function. The type can be used standalone to get n-th part of the sequence or efficiently placed in a loop to find parts in a row (not necessarily beginning at 1) as it has memory of previous parts. (compiler: gfortran 4.8).
The type is defined in mymod.f90 file as
module mymod
implicit none
type seq_t
integer :: saved_i = 0, saved_val_i = 0, saved_val_i_1 = 0
contains
procedure :: getpart => getpart_seq
end type
contains
recursive function getpart_seq(this,i) result(r)
class(seq_t) :: this
integer, intent(in) :: i
integer :: r,r_1,r_2
if (i.eq.1.or.i.eq.2) then
r = 1
elseif(i.eq.this%saved_i) then
r = this%saved_val_i
elseif(i.eq.this%saved_i-1) then
r = this%saved_val_i_1
else
r_1 = this%getpart(i-1)
r_2 = this%getpart(i-2)
r = 2*r_1 + 3*r_2
this%saved_val_i_1 = r_1
end if
this%saved_i = i
this%saved_val_i = r
end function getpart_seq
end module mymod
The main program for the requested case is
program main
use mymod
implicit none
type (seq_t) :: seq
integer :: i,p,tmp_new,tmp_old,ans
! Set the threshold here
p = 90
! loop over parts of the sequence
i = 0
do
i = i + 1
tmp_new = seq%getpart(i)
print*,tmp_new
if (tmp_new>p) then
ans = tmp_old
exit
end if
tmp_old = tmp_new
end do
print*,"The last part of sequence less then",p," is equal to",ans
end program
The outcome is
1
1
5
13
41
121
The last part of sequence less then 90 is equal to 41.

How to change string value label

Suppose I have a string variable that takes on several string values:
gen rand = runiform()
sort rand
gen var1 = ""
replace var1 = "A" if rand < .3
replace var1 = "B" if rand>=.3 & rand < .7
replace var1 = "C" if var1==""
How would I change the values of var1? For example, A to be Aaa, B to be Bbb, and C to be Ccc?
I want to do something like the following (but rather replace the variables), which I know is incorrect:
label define var1L "A" "Aa" B "Bbb" C "Ccc"
label values var1 var1L
String variables can't have value labels. You can interpret this as if labels for string variables are meant to be the content of the variable itself. But you can replace:
clear
set more off
input ///
str1 var1
A
B
C
end
list
replace var1 = "Aaa" if var1 == "A"
replace var1 = "Bbb" if var1 == "B"
replace var1 = "Ccc" if var1 == "C"
list
You need to say more about your data and objectives for a more useful answer.

Multi-Group Column Count Linq

I have,
A list, MyList, of objects with fields:
string A;
string B;
Conceptually, this is similar to a two column SQL Table with columns A, B.
I'm trying to create a linq expression that would produce the three column result set of this T-SQL on such a conceptual table:
SELECT A, B, COUNT(B)
FROM T1
GROUP BY A, B
That is, if I had a table such as:
A B
----------
x g
x g
x g
x s
y g
y g
I would expect:
A B COUNT(B)
-------------------------
x g 3
x s 1
y g 2
My best efforts were this:
var result = from MyObjs in MyList
group MyObjs by new { MyObjs.A, MyObjs.B } into g
select new { g.Key.A, g.Key.B, g.Key.B.Count() }
But the count appears to return the total number of B's not the number of B's per multiple column group. How can this be fixed?
Try this.... (off the top of my head)
var result = from MyObjs in MyList
group MyObjs by new { MyObjs.A, MyObjs.B } into g
select new { g.Key.A, g.Key.B, MyCount = g.Count() }
Or if you prefer...
var result = MyList.GroupBy(x => new {x.A, x.B})
.Select(g => new {g.Key.A, g.Key.B, MyCount = g.Count()});

Swap two integers without using a third variable

I have an assignment in which I need to swap two integers without using third variable.
I'm not sure how to do this. How would I code this?
Yes, it's possible:
Dim var1 = 1
Dim var2 = 2
var1 = var1 + var2
var2 = var1 - var2
var1 = var1 - var2
But why do you need it? The code becomes abstruse.
Lets assume
a = 10;
b = 20;
a = a + b; // a = 30
b = a - b; // b = 10
a = a - b; // a = 20
Values swapped.
Read up on the "xor swap algorithm."
You can find an answer here:
http://www.java2s.com/Tutorial/VB/0040__Data-Type/Swaptwointegerswithoutusingathird.htm
firstValue = firstValue Xor secondValue
secondValue = firstValue Xor secondValue
firstValue = firstValue Xor secondValue
Dim a As Integer
Dim b As Integer
a= 1
b= 2
a = a Xor b
b = a Xor b
a = a Xor b
To swap two numeric variables do like this
a = a + b;
b = a - b;
a = a - b;
OR
a = a xor b;
b = a xor b;
a = a xor b;
where a and b are variables to be swapped
theoretically 3 ways
a = 4 , b = 5
1. Using XOR
a = a XOR b = 4 XOR 5 = 9
b = a XOR b = 9 XOR 5 = 4
a = a XOR b = 9 XOR 4 = 5
2. Using +,-
a = a+b = 4+5 = 9 // should not overflow
b = a-b = 9-5 = 4
a = a-b = 9-4 = 5
3. Using *,/
a = a*b = 4*5 = 20 // should not overflow
b = a/b = 20/5 = 4 // should not overflow and should not be irrational number
a = a/b = 20/4 = 5 // should not overflow and should not be irrational number
The Xor or a+b algorithms above work and are the best way to do this, but just an example of a weird way to do it. Still not sure why you would want to do this. Just build a function that you supply two values ByRef and have it do the standard swap method.
Dim newList as New List(Of Integer)
newList.Add firstvalue
newList.Add secondValue
newList.Reverse
secondValue = newList.Item(0)
firstValue = newList.Item(1)
Take two text boxes and a command box.In command box type this code.
text1.text=val(text1.text) + val(text2.text)
text2.text=val(text1.text) - val(text2.text)
text1.text=val(text1.text) - val(text2.text)
Check link written for you
Approach#1.
Addition and Subtraction Method
Integer a, b
read a and b
a= a+b;
b=a-b;
a=a-b;
Problem:
Incorrect result when sum of numbers will exceed the Integer range.
Approach#2.
Multiplication and Division Method
Integer a, b
read a and b
a=a*b;
b=a/b;
a=a/b;
Problems:
If the value of a*b exceeds the range of integer.
If the value of a or b is zero then it will give wrong results.
Approach#3.
XOR Method
Integer a , b
read a and b
a=a^b;
b=a^b;
a=a^b;
Best approach to solve this problem without any pitfalls.